blob: 6b121342045810c33f1a7931b94fe01bae89ce76 [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
bseeniva33968f02026-01-30 18:49:48 +0530182 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
183 chReconcilingStopped chan struct{} //channel to indicate the current reconciling has been stopped
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530184 pLastUpgradeImageState *voltha.ImageState
185 upgradeFsmChan chan struct{}
186
187 deviceDeleteCommChan chan bool
188 DeviceID string
189 DeviceType string
190 adminState string
191 logicalDeviceID string
192 ProxyAddressID string
193 ProxyAddressType string
194 parentID string
195
196 flowCbChan []chan FlowCb
197 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
198 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
199 reconcileExpiryComplete time.Duration
200 reconcileExpiryVlanConfig time.Duration
201 lockDevice sync.RWMutex
202 mutexDeviceReason sync.RWMutex
203 mutexCollectorFlag sync.RWMutex
204 mutextAlarmManagerFlag sync.RWMutex
205 lockVlanConfig sync.RWMutex
206 lockVlanAdd sync.RWMutex
207 lockUpgradeFsm sync.RWMutex
208 mutexReconcilingFlag sync.RWMutex
209 mutexReconcilingFirstPassFlag sync.RWMutex
210 mutexReconcilingReasonUpdate sync.RWMutex
211 mutexReadyForOmciConfig sync.RWMutex
212 mutexDeletionInProgressFlag sync.RWMutex
213 mutexFlowMonitoringRoutineFlag sync.RWMutex
214 mutexForDisableDeviceRequested sync.RWMutex
215 mutexOltAvailable sync.RWMutex
216 mutexKvStoreContext sync.Mutex
217 ponPortNumber uint32
218
219 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000221 //flowMgr *OpenOltFlowMgr
222 //eventMgr *OpenOltEventMgr
223 //resourceMgr *rsrcMgr.OpenOltResourceMgr
224
225 //discOnus sync.Map
226 //onus sync.Map
227 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530228 collectorIsRunning bool
229 alarmManagerIsRunning bool
230 upgradeCanceled bool
231 reconciling uint8
232 reconcilingFirstPass bool
233 reconcilingReasonUpdate bool
234 readyForOmciConfig bool
235 deletionInProgress bool
236 disableDeviceRequested bool // this flag identify ONU received disable request or not
237 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238}
239
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530240// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400241func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530242 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400243 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400245 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000247 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.DeviceType = cloned.Type
249 dh.adminState = "up"
250 dh.device = cloned
251 dh.pOpenOnuAc = adapter
252 dh.exitChannel = make(chan int, 1)
253 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000254 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000255 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530257 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530258 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 dh.stopHeartbeatCheck = make(chan bool, 2)
260 //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 +0000261 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000262 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000263 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000264 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000265 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300266 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000267 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000268 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000269 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000270 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300271 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000272 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000273 dh.chReconcilingFinished = make(chan bool)
bseeniva33968f02026-01-30 18:49:48 +0530274 dh.chReconcilingStopped = make(chan struct{})
mpagenko101ac942021-11-16 15:01:29 +0000275 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
276 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
277 if rECSeconds < 2 {
278 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
279 rECSeconds = 2
280 }
281 rEVCSeconds := rECSeconds / 2
282 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000283 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000284 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000285 dh.pLastUpgradeImageState = &voltha.ImageState{
286 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
287 Reason: voltha.ImageState_UNKNOWN_ERROR,
288 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
289 }
290 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530291 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800293 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
294 dh.pmConfigs = cloned.PmConfigs
295 } /* else {
296 // will be populated when onu_metrics_mananger is initialized.
297 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800298
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299 // Device related state machine
300 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000301 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000303 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
304 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
305 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
306 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
307 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308 },
309 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
311 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
312 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
313 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
314 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
315 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
316 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
317 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 },
319 )
mpagenkoaf801632020-07-03 10:00:42 +0000320
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 return &dh
322}
323
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324// start save the device to the data model
325func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000326 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000328 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329}
330
Himani Chawla4d908332020-08-31 12:30:20 +0530331/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530333func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334 logger.Debug("stopping-device-handler")
335 dh.exitChannel <- 1
336}
Himani Chawla4d908332020-08-31 12:30:20 +0530337*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338
339// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530340// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530342// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530343func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400344 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000346 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530347
mpagenko1cc3cb42020-07-27 15:24:38 +0000348 if dh.pDeviceStateFsm.Is(devStNull) {
349 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000350 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 +0000351 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000352 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800353 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
354 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800355 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400356 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000357 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800358 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800359 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000362 }
363
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000364}
365
khenaidoo42dcdfd2021-10-19 17:34:12 -0400366func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000367 /* 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 +0530368 //assuming omci message content is hex coded!
369 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000372 */
bseenivacfcd8f72026-01-30 21:06:49 +0530373 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000375 if pDevEntry.PDevOmciCC != nil {
bseenivacfcd8f72026-01-30 21:06:49 +0530376 logger.Debugw(ctx, "pDevEntry.PDevOmciCC is not nil", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000377 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000378 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000379 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
380 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
383 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530384}
385
khenaidoo42dcdfd2021-10-19 17:34:12 -0400386func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000388
bseenivacfcd8f72026-01-30 21:06:49 +0530389 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
392 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530394 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530395 if dh.pOnuTP == nil {
396 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000397 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530399 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000402 if !dh.IsReadyForOmciConfig() {
403 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
404 "device-state": dh.GetDeviceReasonString()})
bseeniva0cbc62a2026-01-23 19:08:36 +0530405 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000408 //previous state test here was just this one, now extended for more states to reject the SetRequest:
409 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
410 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530411
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
414 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000415 dh.pOnuTP.LockTpProcMutex()
416 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530417 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418
mpagenko44bd8362021-11-15 11:40:05 +0000419 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530420 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
421 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000422 }
423 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000424 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800425 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000426 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
427 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800428 return err
429 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000430 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
431 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000433 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530434
Girish Gowdra50e56422021-06-01 16:46:04 -0700435 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400436 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000437 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
438 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000439
440 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
441 if err != nil {
442 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
443 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
444 // stopping all further processing
445 _ = dh.UpdateInterface(ctx)
446 return err
447 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 // if there has been some change for some uni TechProfilePath
449 //in order to allow concurrent calls to other dh instances we do not wait for execution here
450 //but doing so we can not indicate problems to the caller (who does what with that then?)
451 //by now we just assume straightforward successful execution
452 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
453 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530454
Girish Gowdra50e56422021-06-01 16:46:04 -0700455 // deadline context to ensure completion of background routines waited for
456 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
457 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
458 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000459
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700461
462 var wg sync.WaitGroup
463 wg.Add(1) // for the 1 go routine to finish
464 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700466 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000467 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
468 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 -0700469 return tpErr
470 }
471 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
472 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530473 defer cancel2()
474 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
475 if err1 != nil {
476 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
477 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700478 }
479 return nil
480 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000481 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700482 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700483 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000486 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
487 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 return nil
489}
490
khenaidoo42dcdfd2021-10-19 17:34:12 -0400491func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000492 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530493
bseeniva0cbc62a2026-01-23 19:08:36 +0530494 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 if dh.pOnuTP == nil {
496 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530499 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530501 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000503 dh.pOnuTP.LockTpProcMutex()
504 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530505 defer dh.lockDevice.RUnlock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530506
mpagenko0f543222021-11-03 16:24:14 +0000507 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
508 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
509 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530510 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
511 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000512 }
513 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000514 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800515 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000516 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
517 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800518 return err
519 }
mpagenko0f543222021-11-03 16:24:14 +0000520 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
521 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000522 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523
Mahir Gunyel9545be22021-07-04 15:53:16 -0700524 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000525 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526
Himani Chawla26e555c2020-08-31 12:30:20 +0530527}
528
khenaidoo42dcdfd2021-10-19 17:34:12 -0400529func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000530 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 +0000531
bseenivacfcd8f72026-01-30 21:06:49 +0530532 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
535 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000536 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530537 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530538 if dh.pOnuTP == nil {
539 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000541 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530542 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 }
545
Himani Chawla26e555c2020-08-31 12:30:20 +0530546 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000547 dh.pOnuTP.LockTpProcMutex()
548 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530549 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000550
mpagenko0f543222021-11-03 16:24:14 +0000551 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
552 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
553 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530554 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
555 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000556 }
557 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700558 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800560 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000561 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
562 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800563 return err
564 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530566
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000567 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
568 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530569 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000570 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 +0530571 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
572 if err1 != nil {
573 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
574 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000575 }
576
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000579
Mahir Gunyel9545be22021-07-04 15:53:16 -0700580}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000581
Mahir Gunyel9545be22021-07-04 15:53:16 -0700582func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
bseenivacfcd8f72026-01-30 21:06:49 +0530584 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700585 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
587 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530588 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700589 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700591 resourceName = "Gem"
592 } else {
593 resourceName = "Tcont"
594 }
595
596 // deadline context to ensure completion of background routines waited for
597 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
598 dctx, cancel := context.WithDeadline(context.Background(), deadline)
599
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000600 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700601
602 var wg sync.WaitGroup
603 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000604 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700605 resource, entryID, &wg)
606 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
608 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700609 return err
610 }
611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
613 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
614 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
615 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700616 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530617 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700618 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000619 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 +0530620 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
621 if err != nil {
622 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700623 return err
624 }
625 }
626 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000627 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700628 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530629 return nil
630}
631
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530632// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000633func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400634 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400635 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700636 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
637 var errorsList []error
638 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530639 if dh.GetPersRebootFlag(ctx) {
bseenivabc19dec2026-02-04 11:56:23 +0530640 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 +0530641 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
642 }
mpagenko01e726e2020-10-23 09:45:29 +0000643 //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 +0000644 if apOfFlowChanges.ToRemove != nil {
645 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000646 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 "device-id": dh.DeviceID})
649 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700650 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000651 continue
652 }
653 flowInPort := flow.GetInPort(flowItem)
654 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000655 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
656 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700657 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000658 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000660 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000661 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000663 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000664 continue
665 } else {
666 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000668 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
669 loUniPort = uniPort
670 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000671 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000672 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000673 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700675 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000676 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000677 }
678 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000680 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
681 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700682
683 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
684 // Step1 : Fill flowControlBlock
685 // Step2 : Push the flowControlBlock to ONU channel
686 // Step3 : Wait on response channel for response
687 // Step4 : Return error value
688 startTime := time.Now()
689 respChan := make(chan error)
690 flowCb := FlowCb{
691 ctx: ctx,
692 addFlow: false,
693 flowItem: flowItem,
694 flowMetaData: nil,
695 uniPort: loUniPort,
696 respChan: &respChan,
697 }
698 dh.flowCbChan[loUniPort.UniID] <- flowCb
699 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
700 // Wait on the channel for flow handlers return value
701 retError = <-respChan
702 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
703 if retError != nil {
704 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
705 log.Fields{"device-id": dh.DeviceID, "error": retError})
706 errorsList = append(errorsList, retError)
707 continue
708 }
709 } else {
710 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
711 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000712 }
713 }
714 }
715 }
mpagenko01e726e2020-10-23 09:45:29 +0000716 if apOfFlowChanges.ToAdd != nil {
717 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
718 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 "device-id": dh.DeviceID})
721 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700722 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000723 continue
724 }
725 flowInPort := flow.GetInPort(flowItem)
726 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000727 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
728 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700729 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000730 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000732 } else if flowInPort == dh.ponPortNumber {
733 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000735 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000736 continue
737 } else {
738 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000739 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000740 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
741 loUniPort = uniPort
742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000745 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000746 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700747 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000748 continue
mpagenko01e726e2020-10-23 09:45:29 +0000749 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000750 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
751 // if not, we just throw some error here to have an indication about that, if we really need to support that
752 // then we would need to create some means to activate the internal stored flows
753 // after the device gets active automatically (and still with its dependency to the TechProfile)
754 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
755 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756 if !dh.IsReadyForOmciConfig() {
757 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
758 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700759 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
760 errorsList = append(errorsList, retError)
761 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000762 }
763
mpagenko01e726e2020-10-23 09:45:29 +0000764 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000766 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
767 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700768 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
769 // Step1 : Fill flowControlBlock
770 // Step2 : Push the flowControlBlock to ONU channel
771 // Step3 : Wait on response channel for response
772 // Step4 : Return error value
773 startTime := time.Now()
774 respChan := make(chan error)
775 flowCb := FlowCb{
776 ctx: ctx,
777 addFlow: true,
778 flowItem: flowItem,
779 flowMetaData: apFlowMetaData,
780 uniPort: loUniPort,
781 respChan: &respChan,
782 }
783 dh.flowCbChan[loUniPort.UniID] <- flowCb
784 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
785 // Wait on the channel for flow handlers return value
786 retError = <-respChan
787 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
788 if retError != nil {
789 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
790 log.Fields{"device-id": dh.DeviceID, "error": retError})
791 errorsList = append(errorsList, retError)
792 continue
793 }
794 } else {
795 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
796 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000797 }
798 }
799 }
800 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700801 if len(errorsList) > 0 {
802 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
803 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
804 }
805 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000806}
807
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530808// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
809// following are the expected device states after this activity:
810// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000811// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000812func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
813 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300814 dh.mutexForDisableDeviceRequested.Lock()
815 dh.disableDeviceRequested = true
816 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000817 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000818 //note that disableDevice sequences in some 'ONU active' state may yield also
819 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000820 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000822 //disable-device shall be just a UNi/ONU-G related admin state setting
823 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000824
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000826 // disable UNI ports/ONU
827 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
828 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000830 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000832 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000833 }
834 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000835 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000837 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400838 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000840 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400841 OperStatus: voltha.OperStatus_UNKNOWN,
842 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000843 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000845 }
mpagenko01e726e2020-10-23 09:45:29 +0000846 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000847
848 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000849 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000850 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300851 }
852}
853
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530854// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
856 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000857
mpagenkoaa3afe92021-05-21 16:20:58 +0000858 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000859 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
860 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
861 // for real ONU's that should have nearly no influence
862 // Note that for real ONU's there is anyway a problematic situation with following sequence:
863 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
864 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
865 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000867
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000868 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300870 dh.mutexForDisableDeviceRequested.Lock()
871 dh.disableDeviceRequested = false
872 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000873 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000875 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000878 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300879}
880
dbainbri4d3a0dc2020-12-02 00:33:42 +0000881func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530882 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 return
888 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000890 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000891 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000892 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000894 }
mpagenko101ac942021-11-16 15:01:29 +0000895 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000897 }
Himani Chawla4d908332020-08-31 12:30:20 +0530898 var onuIndication oop.OnuIndication
akashreddykb03dde02025-12-02 10:53:18 +0530899 var rebootInProgress bool
900 var persUniUnlockDone bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 pDevEntry.MutexPersOnuConfig.RLock()
902 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
903 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
904 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
905 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
akashreddykb03dde02025-12-02 10:53:18 +0530906 rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
907 persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000908 pDevEntry.MutexPersOnuConfig.RUnlock()
akashreddykb03dde02025-12-02 10:53:18 +0530909 if rebootInProgress {
910 if persUniUnlockDone {
911 logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
912 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
913 return
914 }
915 }
916 if onuIndication.OperState == "up" {
917 if err := dh.createInterface(ctx, &onuIndication); err != nil {
918 logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
919 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
920 return
921 }
922 } else {
923 logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
924 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
925 return
926 }
927 logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000928}
929
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000930func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530931 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000932
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000933 continueWithFlowConfig := false
934
bseenivacfcd8f72026-01-30 21:06:49 +0530935 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000936 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000938 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
939 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000940 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530941 dh.lockDevice.RLock()
942 if dh.pOnuTP == nil {
943 //should normally not happen ...
944 logger.Warnw(ctx, "onuTechProf instance not set up for reconcile tech prof - ignoring request",
945 log.Fields{"device-id": dh.DeviceID})
946 dh.lockDevice.RUnlock()
947 return continueWithFlowConfig
948 }
949
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 dh.pOnuTP.LockTpProcMutex()
951 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530952 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000953
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000955 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
957 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530958 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000959 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000960 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
961 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000962 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000963 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700964 techProfsFound := false
965 techProfInstLoadFailed := false
966outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000968 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000969 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000970 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000972 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000974 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
976 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000977 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000979 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700980 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000981 var iaTechTpInst ia.TechProfileDownloadMessage
982 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800983 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000984 pDevEntry.MutexReconciledTpInstances.RLock()
985 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
986 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000987 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000988 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000990 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700991 break outerLoop
992 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000993 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000994 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700995 var tpInst tech_profile.TechProfileInstance
996 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400997 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700998 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000999 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", 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 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001002 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001004 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1005 break outerLoop
1006 }
1007
Girish Gowdra041dcb32020-11-16 16:54:30 -08001008 // deadline context to ensure completion of background routines waited for
1009 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
1010 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001011 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001012
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001013 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001014 var wg sync.WaitGroup
1015 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001018 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
1019 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001020 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1021 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -08001022 }
mpagenko2dc896e2021-08-02 12:03:59 +00001023 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024 if len(uniData.PersFlowParams) != 0 {
1025 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001026 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001027 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +00001028 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 } // for all UNI entries from SOnuPersistentData
1030 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
1031 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001032 }
mpagenko2dc896e2021-08-02 12:03:59 +00001033
1034 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1035 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001036
1037 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +00001038}
1039
1040func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1041 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1042 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301043 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001045 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001046 return
1047 }
mpagenko2dc896e2021-08-02 12:03:59 +00001048 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001049 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001050 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001051 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001053 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001054 }
mpagenko2dc896e2021-08-02 12:03:59 +00001055 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301056 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001058 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001059 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060}
1061
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001062func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1063 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064
bseenivacfcd8f72026-01-30 21:06:49 +05301065 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001066 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001067 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001068 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001069 return
1070 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001071
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001072 pDevEntry.MutexPersOnuConfig.RLock()
1073 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1074 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301075 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001076 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001077 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001078 return
1079 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001080 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001081 var uniVlanConfigEntries []uint8
1082 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1083
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001084 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001085 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1086 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001087 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001088 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001089 continue
1090 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001091 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001092 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001093 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001094 // It doesn't make sense to configure any flows if no TPs are available
1095 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001096 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001097 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1098 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001099 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001100 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001101
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001102 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001104 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001105 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001106 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1107 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001108 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001109 return
1110 }
mpagenko101ac942021-11-16 15:01:29 +00001111 //needed to split up function due to sca complexity
1112 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1113
mpagenko2dc896e2021-08-02 12:03:59 +00001114 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001115 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001116 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1117 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001118 // this can't be used as global finished reconciling flag because
1119 // assumes is getting called before the state machines for the last flow is completed,
1120 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001121 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1122 } // for all UNI entries from SOnuPersistentData
1123 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001124
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001125 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301126 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001128 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001129 return
1130 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001131 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1132 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1133 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1134 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1135 log.Fields{"device-id": dh.DeviceID})
1136 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1137 if pDevEntry != nil {
1138 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001139 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001140 } else {
1141 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1142 log.Fields{"device-id": dh.DeviceID})
1143 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1144 if pDevEntry != nil {
1145 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1146 }
1147 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001148 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001149 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001150}
1151
mpagenko101ac942021-11-16 15:01:29 +00001152func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1153 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1154 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1155 flowsProcessed := 0
1156 lastFlowToReconcile := false
1157 loUniID := apUniPort.UniID
1158 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001159 if !(*apFlowsFound) {
1160 *apFlowsFound = true
1161 syncChannel := make(chan struct{})
1162 // start go routine with select() on reconciling vlan config channel before
1163 // starting vlan config reconciling process to prevent loss of any signal
1164 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1165 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1166 //block until the wait routine is really blocked on channel input
1167 // in order to prevent to early ready signal from VlanConfig processing
1168 <-syncChannel
1169 }
1170 if flowsProcessed == len(aPersFlowParam)-1 {
1171 var uniAdded bool
1172 lastFlowToReconcile = true
1173 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1174 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001175 }
1176 }
mpagenko101ac942021-11-16 15:01:29 +00001177 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1178 "device-id": dh.DeviceID, "uni-id": loUniID,
1179 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1180 dh.lockVlanConfig.Lock()
1181 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1182 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1183 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301184 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 +00001185 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1186 }
1187 } else {
1188 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301189 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301190 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001191 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1192 }
1193 }
1194 dh.lockVlanConfig.Unlock()
1195 flowsProcessed++
1196 } //for all flows of this UNI
1197}
1198
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301199// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1200//
1201// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001202func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1203 waitGroup *cmn.WaitGroupWithTimeOut) {
1204 var reconciledUniVlanConfigEntries []uint8
1205 var appended bool
1206 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1207 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1208 "device-id": dh.DeviceID, "expiry": expiry})
1209 // indicate blocking on channel now to the caller
1210 aSyncChannel <- struct{}{}
1211 for {
1212 select {
1213 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1214 switch uniIndication {
1215 // no activity requested (should normally not be received) - just continue waiting
1216 case cWaitReconcileFlowNoActivity:
1217 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1218 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301219 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001220 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1221 return
1222 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1223 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301224 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001225 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1226 return
1227 // this should be a valid UNI vlan config done indication
1228 default:
1229 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301230 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001231 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1232 if reconciledUniVlanConfigEntries, appended =
1233 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1234 waitGroup.Done()
1235 }
1236 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301237 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 +00001238 }
1239 } //switch uniIndication
1240
1241 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1242 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1243 log.Fields{"device-id": dh.DeviceID})
1244 return
1245 }
1246 }
1247}
1248
1249func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1250 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1251}
1252
1253func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1254 for _, ele := range slice {
1255 if ele == val {
1256 return slice, false
1257 }
1258 }
1259 return append(slice, val), true
1260}
1261
1262// sendChReconcileFinished - sends true or false on reconcileFinish channel
1263func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1264 if dh != nil { //if the object still exists (might have been already deleted in background)
1265 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1266 select {
1267 case dh.chReconcilingFinished <- success:
1268 default:
1269 }
bseeniva33968f02026-01-30 18:49:48 +05301270 // Wait until the current running reconciliation has stopped
1271 <-dh.chReconcilingStopped
mpagenko101ac942021-11-16 15:01:29 +00001272 }
1273}
1274
1275// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1276func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1277 if dh != nil { //if the object still exists (might have been already deleted in background)
1278 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1279 select {
1280 case dh.chUniVlanConfigReconcilingDone <- value:
1281 default:
1282 }
1283 }
1284}
1285
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301286func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1287 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1288
1289 defer dh.UpdateAndStoreRebootState(ctx, false)
1290 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1291 if pDevEntry == nil {
1292 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1293 return
1294 }
1295
1296 pDevEntry.MutexPersOnuConfig.RLock()
1297 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1298 pDevEntry.MutexPersOnuConfig.RUnlock()
1299 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1300 log.Fields{"device-id": dh.DeviceID})
1301 return
1302 }
1303 flowsFound := false
1304 var uniVlanConfigEntries []uint8
1305 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1306
1307 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1308 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1309 if len(uniData.PersFlowParams) == 0 {
1310 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1311 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1312 continue
1313 }
1314 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1315 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1316 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1317 // It doesn't make sense to configure any flows if no TPs are available
1318 continue
1319 }
1320 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1321 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1322 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1323 pDevEntry.MutexPersOnuConfig.RUnlock()
1324
1325 var uniPort *cmn.OnuUniPort
1326 var exist bool
1327 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1328 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1329 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1330 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1331 return
1332 }
1333
1334 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1335
1336 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1337 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1338 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1339 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1340 // this can't be used as global finished reconciling flag because
1341 // assumes is getting called before the state machines for the last flow is completed,
1342 // while this is not guaranteed.
1343 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1344 } // for all UNI entries from SOnuPersistentData
1345 pDevEntry.MutexPersOnuConfig.RUnlock()
1346
1347 if !flowsFound {
1348 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1349 log.Fields{"device-id": dh.DeviceID})
1350 return
1351 }
1352 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1353 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1354 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1355 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1356 log.Fields{"device-id": dh.DeviceID})
1357 } else {
1358 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1359 log.Fields{"device-id": dh.DeviceID})
1360 return
1361 }
1362}
1363
1364func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1365 dh.UpdateRebootPersData(ctx, flag)
1366 if err := dh.StorePersistentData(ctx); err != nil {
1367 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1368 }
1369}
1370
1371func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1372 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1373 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1374 flowsProcessed := 0
1375 lastFlowToConfigOnReboot := false
1376 loUniID := apUniPort.UniID
1377 for _, flowData := range aPersFlowParam {
1378 if !(*apFlowsFound) {
1379 *apFlowsFound = true
1380 syncChannel := make(chan struct{})
1381 // start go routine with select() on reconciling vlan config channel before
1382 // starting vlan config reconciling process to prevent loss of any signal
1383 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1384 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1385 //block until the wait routine is really blocked on channel input
1386 // in order to prevent to early ready signal from VlanConfig processing
1387 <-syncChannel
1388 }
1389 if flowsProcessed == len(aPersFlowParam)-1 {
1390 var uniAdded bool
1391 lastFlowToConfigOnReboot = true
1392 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1393 apWaitGroup.Add(1) //increment the waiting group
1394 }
1395 }
1396 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1397 "device-id": dh.DeviceID, "uni-id": loUniID,
1398 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1399 dh.lockVlanConfig.Lock()
1400 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1401 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1402 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1403 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 {
1404 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1405 }
1406 } else {
1407 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1408 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1409 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1410 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1411 }
1412 }
1413 dh.lockVlanConfig.Unlock()
1414 flowsProcessed++
1415 } //for all flows of this UNI
1416}
1417
1418func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1419 waitGroup *cmn.WaitGroupWithTimeOut) {
1420 var rebootUniVlanConfigEntries []uint8
1421 var appended bool
1422 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1423 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1424 "device-id": dh.DeviceID, "expiry": expiry})
1425 // indicate blocking on channel now to the caller
1426 aSyncChannel <- struct{}{}
1427 for {
1428 select {
1429 case <-dh.deviceDeleteCommChan:
1430 // Cancel the context and return
1431 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1432 return
1433
1434 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1435 switch uniIndication {
1436 // this should be a valid UNI vlan config done indication
1437 default:
1438 if uniIndication < platform.MaxUnisPerOnu {
1439 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1440 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1441 if rebootUniVlanConfigEntries, appended =
1442 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1443 waitGroup.Done()
1444 }
1445 } else {
1446 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1447 }
1448 } //switch uniIndication
1449
1450 case <-time.After(expiry):
1451 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1452 log.Fields{"device-id": dh.DeviceID})
1453 return
1454 }
1455 }
1456}
1457
1458func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1459 if dh != nil { //if the object still exists (might have been already deleted in background)
1460 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1461 select {
1462 case dh.chUniVlanConfigOnRebootDone <- value:
1463 default:
1464 }
1465 }
1466}
1467
1468func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
bseenivabc19dec2026-02-04 11:56:23 +05301469 logger.Infow(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301470 techProfInstLoadFailed := false
1471 continueWithFlowConfig := false
1472 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1473 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1474 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1475
1476 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1477 if pDevEntry == nil {
1478 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1479 return continueWithFlowConfig
1480 }
1481 dh.lockDevice.RLock()
1482 if dh.pOnuTP == nil {
1483 //should normally not happen ...
1484 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1485 log.Fields{"device-id": dh.DeviceID})
1486 dh.lockDevice.RUnlock()
1487 return continueWithFlowConfig
1488 }
1489
1490 dh.pOnuTP.LockTpProcMutex()
1491 defer dh.pOnuTP.UnlockTpProcMutex()
1492 defer dh.lockDevice.RUnlock()
1493
1494 pDevEntry.MutexPersOnuConfig.RLock()
1495 persMutexLock := true
1496 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1497 pDevEntry.MutexPersOnuConfig.RUnlock()
1498 logger.Info(ctx, "no uni-configs have been stored - aborting",
1499 log.Fields{"device-id": dh.DeviceID})
1500 return continueWithFlowConfig
1501 }
1502
1503outerLoop:
1504 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1505 uniID := uniData.PersUniID
1506
1507 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1508 logger.Debugw(ctx, "no TPs stored for uniID",
1509 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1510 continue
1511 }
1512 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1513 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1514 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1515 pDevEntry.MutexPersOnuConfig.RUnlock()
1516 persMutexLock = false
1517 for tpID, tpPath := range uniData.PersTpPathMap {
1518 if tpPath != "" {
1519 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1520 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1521 })
1522 // Attempt the initial call before entering the retry loop
1523 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1524 if err != nil {
1525 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1526 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1527 })
1528 techProfInstLoadFailed = true
1529 break outerLoop
1530 }
1531 if iaTechTpInst != nil {
1532 var tpInst tech_profile.TechProfileInstance
1533 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1534 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1535 tpInst = *techTpInst.TpInstance
1536 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1537 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1538 default: // do not support epon or other tech
1539 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1540 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1541 techProfInstLoadFailed = true
1542 break outerLoop
1543 }
1544
1545 continueWithFlowConfig = true
1546 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1547 dctx, cancel := context.WithDeadline(ctx, deadline)
1548
1549 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1550 var wg sync.WaitGroup
1551 wg.Add(1) // for the 1 go routine to finish
1552 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1553 // Wait for either completion or cancellation
1554 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1555 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1556 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1557 techProfInstLoadFailed = true
1558 continueWithFlowConfig = false
1559 break outerLoop
1560 }
1561 } else {
1562 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1563 techProfInstLoadFailed = true
1564 break outerLoop
1565 }
1566 } else {
1567 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1568 "uni-id": uniID, "device-id": dh.DeviceID})
1569 techProfInstLoadFailed = true
1570 break outerLoop
1571 }
1572 }
1573 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1574 persMutexLock = true
1575 }
1576 if persMutexLock {
1577 pDevEntry.MutexPersOnuConfig.RUnlock()
1578 }
1579 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1580 return continueWithFlowConfig
1581}
1582
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001587 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001588 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001589 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001590 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001591 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001592
1593 // deadline context to ensure completion of background routines waited for
1594 //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 +05301595 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301597 defer cancel()
1598 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1599 if err != nil {
1600 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1601 return err
1602 }
1603 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001604}
1605
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301606// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001607// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301608//
1609// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1610//
1611// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301612func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001614 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301616 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001617 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001618 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301619 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301621 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301622 }
mpagenko01e726e2020-10-23 09:45:29 +00001623
1624 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001626
mpagenko44bd8362021-11-15 11:40:05 +00001627 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001629 // 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 +05301630 go func() {
1631 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1632 DeviceId: dh.DeviceID,
1633 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1634 OperStatus: voltha.OperStatus_DISCOVERED,
1635 }); err != nil {
1636 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1637 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1638 return
1639 }
bseenivabc19dec2026-02-04 11:56:23 +05301640 if dh.GetDeviceTechProfOnReboot() {
1641 dh.UpdateAndStoreRebootState(ctx, true)
1642 }
akashreddyke30dfa92025-11-26 10:51:57 +05301643 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1644 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1645 return
1646 }
1647 dh.SetReadyForOmciConfig(false)
1648 }()
1649 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001650 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1651 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1652 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1653 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001654}
1655
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301656// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1657//
1658// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001659func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001661 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001663
1664 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301665 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001666 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1668 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001669 }
1670
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001671 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001672 var inactiveImageID uint16
1673 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1674 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001675 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1676 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001677 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001679 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001680 if err == nil {
1681 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1682 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001684 }
1685 } else {
1686 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001688 }
mpagenko15ff4a52021-03-02 10:09:20 +00001689 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001690 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001692 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1693 dh.upgradeCanceled = true
1694 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1695 }
mpagenko38662d02021-08-11 09:45:19 +00001696 //no effort spent anymore for the old API to automatically cancel and restart the download
1697 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001698 }
mpagenko15ff4a52021-03-02 10:09:20 +00001699 } else {
1700 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001702 }
1703 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001704 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1705 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001706 }
1707 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001708}
1709
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301710// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001711// after the OnuImage has been downloaded to the adapter, called in background
1712func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
bseeniva0b4286b2026-01-30 13:05:42 +05301713 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string, aCancel context.CancelFunc) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001714
1715 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301716 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001717 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001718 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001719 return
1720 }
1721
1722 var inactiveImageID uint16
1723 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1724 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001725 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001726
mpagenko59862f02021-10-11 08:53:18 +00001727 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001728 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001729 // but must be still locked at calling createOnuUpgradeFsm
1730 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1731 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1732 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001733 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1734 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001735 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001736 //flush the remove upgradeFsmChan channel
1737 select {
1738 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001739 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001740 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001741 }
mpagenko59862f02021-10-11 08:53:18 +00001742 dh.lockUpgradeFsm.Unlock()
1743 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1744 dh.upgradeCanceled = true
1745 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1746 }
mpagenko38662d02021-08-11 09:45:19 +00001747 select {
1748 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001749 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001750 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1751 return
1752 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001753 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001754 }
mpagenko59862f02021-10-11 08:53:18 +00001755 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001756 }
mpagenko38662d02021-08-11 09:45:19 +00001757
1758 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001759 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001760 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001761 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001762 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001763 if err == nil {
1764 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1765 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1766 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001767 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001768 return
1769 }
mpagenko38662d02021-08-11 09:45:19 +00001770 } else {
1771 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001773 }
bseeniva0b4286b2026-01-30 13:05:42 +05301774 go func() {
1775 onuDlChn := dh.pOnuUpradeFsm.GetOnuDLChannel()
1776 select {
1777 case <-ctx.Done():
1778 logger.Errorw(ctx, "context Deadline Exceeded aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1779 dh.lockUpgradeFsm.Lock()
1780 if dh.pOnuUpradeFsm != nil {
1781 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1782 }
1783 dh.lockUpgradeFsm.Unlock()
1784 return
1785 case <-dh.deviceDeleteCommChan:
1786 logger.Errorw(ctx, "device deleted aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1787 dh.lockUpgradeFsm.Lock()
1788 if dh.pOnuUpradeFsm != nil {
1789 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1790 }
1791 dh.lockUpgradeFsm.Unlock()
1792 return
1793 case success := <-onuDlChn:
1794 logger.Infow(ctx, "onu SW upgrade download completed", log.Fields{"isSuccess": success, "device-id": dh.DeviceID})
1795 aCancel()
1796 return
1797
1798 }
1799 }()
mpagenkoc26d4c02021-05-06 14:27:57 +00001800 return
1801 }
1802 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001803 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001804}
1805
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301806// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001807func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1808 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001809 var err error
1810 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1811 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1812 // 2.) activation of the inactive image
1813
bseenivacfcd8f72026-01-30 21:06:49 +05301814 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001815 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001816 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1817 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001818 }
1819 dh.lockUpgradeFsm.RLock()
1820 if dh.pOnuUpradeFsm != nil {
1821 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001822 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001823 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001824 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1825 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001826 }
mpagenko59862f02021-10-11 08:53:18 +00001827 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1828 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1829 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1830 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001831 // use the OnuVendor identification from this device for the internal unique name
1832 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001833 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001834 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001835 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001836 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 "device-id": dh.DeviceID, "error": err})
1838 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001839 }
mpagenko183647c2021-06-08 15:25:04 +00001840 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001842 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001843 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001844 } //else
1845 dh.lockUpgradeFsm.RUnlock()
1846
1847 // 2.) check if requested image-version equals the inactive one and start its activation
1848 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1849 var inactiveImageID uint16
1850 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1851 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1853 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001854 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001855 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001856 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001857 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001858 if err == nil {
1859 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1860 inactiveImageID, aCommitRequest); err != nil {
1861 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001862 "device-id": dh.DeviceID, "error": err})
1863 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001864 }
1865 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001866 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001867 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001868 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001869 } //else
1870 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001871 "device-id": dh.DeviceID, "error": err})
1872 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001873}
1874
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301875// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001876func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1877 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001878 var err error
1879 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1880 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1881 // 2.) commitment of the active image
1882
bseenivacfcd8f72026-01-30 21:06:49 +05301883 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001884 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001885 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1886 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001887 }
1888 dh.lockUpgradeFsm.RLock()
1889 if dh.pOnuUpradeFsm != nil {
1890 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001891 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001892 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001893 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1894 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001895 }
mpagenko59862f02021-10-11 08:53:18 +00001896 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1897 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1898 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1899 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001900 // use the OnuVendor identification from this device for the internal unique name
1901 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001902 // 1.) check a started upgrade process and relay the commitment request to it
1903 // the running upgrade may be based either on the imageIdentifier (started from download)
1904 // or on the imageVersion (started from pure activation)
1905 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1906 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001907 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 "device-id": dh.DeviceID, "error": err})
1909 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001910 }
mpagenko183647c2021-06-08 15:25:04 +00001911 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001912 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001913 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001914 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001915 } //else
1916 dh.lockUpgradeFsm.RUnlock()
1917
mpagenko183647c2021-06-08 15:25:04 +00001918 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001919 var activeImageID uint16
1920 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1921 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1923 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001924 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001925 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001926 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001927 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001928 if err == nil {
1929 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1930 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001931 "device-id": dh.DeviceID, "error": err})
1932 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001933 }
1934 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001936 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001937 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001938 } //else
1939 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001940 "device-id": dh.DeviceID, "error": err})
1941 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001942}
1943
mpagenkoaa3afe92021-05-21 16:20:58 +00001944func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001945 aVersion string) *voltha.ImageState {
1946 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001947 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001948 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001949 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001950 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1951 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1952 if aVersion == dh.pLastUpgradeImageState.Version {
1953 pImageState = dh.pLastUpgradeImageState
1954 } else { //state request for an image version different from last processed image version
1955 pImageState = &voltha.ImageState{
1956 Version: aVersion,
1957 //we cannot state something concerning this version
1958 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1959 Reason: voltha.ImageState_NO_ERROR,
1960 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1961 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001962 }
1963 }
mpagenko38662d02021-08-11 09:45:19 +00001964 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001965}
1966
1967func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1968 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001970 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001971 dh.lockUpgradeFsm.RLock()
1972 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001973 dh.lockUpgradeFsm.RUnlock()
1974 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001975 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001976 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1977 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1978 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1979 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1980 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1981 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001982 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1983 dh.upgradeCanceled = true
1984 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1985 }
mpagenko45586762021-10-01 08:30:22 +00001986 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001987 } else {
mpagenko45586762021-10-01 08:30:22 +00001988 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001989 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1990 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1991 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1992 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1993 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1994 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001995 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1996 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001997 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1998 //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 +00001999 }
2000}
2001
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002002func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
2003
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002006 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002007 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002008 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
2009 pDevEntry.MutexOnuImageStatus.Lock()
2010 pDevEntry.POnuImageStatus = onuImageStatus
2011 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002012
2013 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002014 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002015 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
2016 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002017 images, err := onuImageStatus.GetOnuImageStatus(ctx)
2018 pDevEntry.MutexOnuImageStatus.Lock()
2019 pDevEntry.POnuImageStatus = nil
2020 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002021 return images, err
2022}
2023
Himani Chawla6d2ae152020-09-02 13:11:20 +05302024// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002025// #####################################################################################
2026
2027// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302028// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002029
dbainbri4d3a0dc2020-12-02 00:33:42 +00002030func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002031 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
2032 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033}
2034
2035// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002037
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002038 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002039 var err error
2040
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002041 // populate what we know. rest comes later after mib sync
2042 dh.device.Root = false
2043 dh.device.Vendor = "OpenONU"
2044 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002045 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00002046 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002047
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002048 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002049
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002050 if !dh.IsReconciling() {
2051 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302052 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002053 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2054 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302055 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002056 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302057 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002058 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002059 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002060
Himani Chawla4d908332020-08-31 12:30:20 +05302061 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002062 dh.ponPortNumber = dh.device.ParentPortNo
2063
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002064 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2065 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2066 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002067 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002068 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302069 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002070
2071 /*
2072 self._pon = PonPort.create(self, self._pon_port_number)
2073 self._pon.add_peer(self.parent_id, self._pon_port_number)
2074 self.logger.debug('adding-pon-port-to-agent',
2075 type=self._pon.get_port().type,
2076 admin_state=self._pon.get_port().admin_state,
2077 oper_status=self._pon.get_port().oper_status,
2078 )
2079 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002080 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302081 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002082 var ponPortNo uint32 = 1
2083 if dh.ponPortNumber != 0 {
2084 ponPortNo = dh.ponPortNumber
2085 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002086
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002087 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002088 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002089 PortNo: ponPortNo,
2090 Label: fmt.Sprintf("pon-%d", ponPortNo),
2091 Type: voltha.Port_PON_ONU,
2092 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302093 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002094 PortNo: ponPortNo}}, // Peer port is parent's port number
2095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002096 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002097 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002098 e.Cancel(err)
2099 return
2100 }
2101 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302102 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002103 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002104 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002105}
2106
2107// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002109
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002110 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002111 var err error
2112 /*
2113 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2114 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2115 return nil
2116 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002118 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002119 e.Cancel(err)
2120 return
2121 }
2122
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002125 // reconcilement will be continued after mib download is done
2126 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002127
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002128 /*
2129 ############################################################################
2130 # Setup Alarm handler
2131 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2132 device.serial_number)
2133 ############################################################################
2134 # Setup PM configuration for this device
2135 # Pass in ONU specific options
2136 kwargs = {
2137 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2138 'heartbeat': self.heartbeat,
2139 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2140 }
2141 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2142 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2143 self.logical_device_id, device.serial_number,
2144 grouped=True, freq_override=False, **kwargs)
2145 pm_config = self._pm_metrics.make_proto()
2146 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2147 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2148 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2149
2150 # Note, ONU ID and UNI intf set in add_uni_port method
2151 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2152 ani_ports=[self._pon])
2153
2154 # Code to Run OMCI Test Action
2155 kwargs_omci_test_action = {
2156 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2157 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2158 }
2159 serial_number = device.serial_number
2160 self._test_request = OmciTestRequest(self.core_proxy,
2161 self.omci_agent, self.device_id,
2162 AniG, serial_number,
2163 self.logical_device_id,
2164 exclusive=False,
2165 **kwargs_omci_test_action)
2166
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002167 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002168 else:
2169 self.logger.info('onu-already-activated')
2170 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002171
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002172 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002173}
2174
2175// doStateConnected get the device info and update to voltha core
2176// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302177//
2178// voltha-openolt-adapter/adaptercore/device_handler.go
2179// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002181
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002182 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302183 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002185 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002186}
2187
2188// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002190
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002191 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302192 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002193 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002194 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002195
2196 /*
2197 // Synchronous call to update device state - this method is run in its own go routine
2198 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2199 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002200 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 +00002201 return err
2202 }
2203 return nil
2204 */
2205}
2206
2207// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002209
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002210 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002211 var err error
2212
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002213 device := dh.device
2214 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002215 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002217 e.Cancel(err)
2218 return
2219 }
2220
2221 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002223 /*
2224 // Update the all ports state on that device to disable
2225 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002226 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002227 return er
2228 }
2229
2230 //Update the device oper state and connection status
2231 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2232 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2233 dh.device = cloned
2234
2235 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002236 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002237 return er
2238 }
2239
2240 //get the child device for the parent device
2241 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2242 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002243 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002244 return err
2245 }
2246 for _, onuDevice := range onuDevices.Items {
2247
2248 // Update onu state as down in onu adapter
2249 onuInd := oop.OnuIndication{}
2250 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002251 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002252 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2253 if er != nil {
2254 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002255 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002256 //Do not return here and continue to process other ONUs
2257 }
2258 }
2259 // * Discovered ONUs entries need to be cleared , since after OLT
2260 // is up, it starts sending discovery indications again* /
2261 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002262 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002263 return nil
2264 */
Himani Chawla4d908332020-08-31 12:30:20 +05302265 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002266 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002267 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002268}
2269
Himani Chawla6d2ae152020-09-02 13:11:20 +05302270// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002271// #################################################################################
2272
2273// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302274// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002275
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302276// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002278 dh.lockDevice.RLock()
2279 pOnuDeviceEntry := dh.pOnuOmciDevice
2280 if aWait && pOnuDeviceEntry == nil {
2281 //keep the read sema short to allow for subsequent write
2282 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002284 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2285 // so it might be needed to wait here for that event with some timeout
2286 select {
2287 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002289 return nil
2290 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002292 // if written now, we can return the written value without sema
2293 return dh.pOnuOmciDevice
2294 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002295 }
mpagenko3af1f032020-06-10 08:53:41 +00002296 dh.lockDevice.RUnlock()
2297 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002298}
2299
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302300// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2302 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002303 dh.lockDevice.Lock()
2304 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002305 dh.pOnuOmciDevice = apDeviceEntry
2306 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002307 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302308 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002309 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002310}
2311
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302312// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302313//
2314//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302315func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002317
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002319 if deviceEntry == nil {
2320 /* costum_me_map in python code seems always to be None,
2321 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2322 /* also no 'clock' argument - usage open ...*/
2323 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002324 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2325 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2326 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2327 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2328 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002329 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002331 // fire deviceEntry ready event to spread to possibly waiting processing
2332 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002334 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002336 }
2337 // might be updated with some error handling !!!
2338 return nil
2339}
2340
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002342 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002343 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2344
2345 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002346
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002348 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2350 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002351 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302352
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002353 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002355 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002356
khenaidoo42dcdfd2021-10-19 17:34:12 -04002357 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002358 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002359 OperStatus: voltha.OperStatus_ACTIVATING,
2360 ConnStatus: voltha.ConnectStatus_REACHABLE,
2361 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002362 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302364 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2365 }
2366 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2367 if dh.GetDeviceTechProfOnReboot() {
2368 pDevEntry.MutexPersOnuConfig.Lock()
2369 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2370 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302371 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302372 pDevEntry.MutexPersOnuConfig.Unlock()
2373 }
2374 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2375 if err := dh.StorePersistentData(ctx); err != nil {
2376 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2377 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002378 }
2379 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302380 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002381 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002382
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 pDevEntry.MutexPersOnuConfig.RLock()
2384 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2385 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 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 +00002387 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002388 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302389
2390 //VOL-4965: Recover previously Activating ONU during reconciliation.
bseeniva33968f02026-01-30 18:49:48 +05302391 // Allow the ONU device to perform mib-reset and follow the standard startup process, if it was previously in the Activating state or
2392 // if its admin state was "up" before the ONU adapter restarted.
2393 pDevEntry.MutexPersOnuConfig.Lock()
2394 if dh.device.OperStatus == common.OperStatus_ACTIVATING || pDevEntry.SOnuPersistentData.PersAdminState == "up" {
2395 logger.Debugw(ctx, "Reconciling an ONU in previously activating state or admin state up, perform MIB reset and resume normal start up",
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302396 log.Fields{"device-id": dh.DeviceID})
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302397 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2398 pDevEntry.MutexPersOnuConfig.Unlock()
bseeniva33968f02026-01-30 18:49:48 +05302399 } else {
2400 pDevEntry.MutexPersOnuConfig.Unlock()
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302401 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002402 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002404 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002405 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002406 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2407 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2408 // 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 +00002409 // 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 +00002410 // so let's just try to keep it simple ...
2411 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002413 if err != nil || device == nil {
2414 //TODO: needs to handle error scenarios
2415 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2416 return errors.New("Voltha Device not found")
2417 }
2418 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002421 return err
mpagenko3af1f032020-06-10 08:53:41 +00002422 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002423 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302424 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2425 /* this might be a good time for Omci Verify message? */
2426 verifyExec := make(chan bool)
2427 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2428 dh.device.Id, pDevEntry.PDevOmciCC, false,
2429 true, true) //exclusive and allowFailure (anyway not yet checked)
2430 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002431
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302432 /* give the handler some time here to wait for the OMCi verification result
2433 after Timeout start and try MibUpload FSM anyway
2434 (to prevent stopping on just not supported OMCI verification from ONU) */
2435 select {
2436 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2437 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2438 case testresult := <-verifyExec:
2439 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2440 case <-dh.deviceDeleteCommChan:
2441 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2442 return nil
2443 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002444 }
2445
2446 /* In py code it looks earlier (on activate ..)
2447 # Code to Run OMCI Test Action
2448 kwargs_omci_test_action = {
2449 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2450 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2451 }
2452 serial_number = device.serial_number
2453 self._test_request = OmciTestRequest(self.core_proxy,
2454 self.omci_agent, self.device_id,
2455 AniG, serial_number,
2456 self.logical_device_id,
2457 exclusive=False,
2458 **kwargs_omci_test_action)
2459 ...
2460 # Start test requests after a brief pause
2461 if not self._test_request_started:
2462 self._test_request_started = True
2463 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2464 reactor.callLater(tststart, self._test_request.start_collector)
2465
2466 */
2467 /* which is then: in omci_test_request.py : */
2468 /*
2469 def start_collector(self, callback=None):
2470 """
2471 Start the collection loop for an adapter if the frequency > 0
2472
2473 :param callback: (callable) Function to call to collect PM data
2474 """
2475 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2476 if callback is None:
2477 callback = self.perform_test_omci
2478
2479 if self.lc is None:
2480 self.lc = LoopingCall(callback)
2481
2482 if self.default_freq > 0:
2483 self.lc.start(interval=self.default_freq / 10)
2484
2485 def perform_test_omci(self):
2486 """
2487 Perform the initial test request
2488 """
2489 ani_g_entities = self._device.configuration.ani_g_entities
2490 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2491 is not None else None
2492 self._entity_id = ani_g_entities_ids[0]
2493 self.logger.info('perform-test', entity_class=self._entity_class,
2494 entity_id=self._entity_id)
2495 try:
2496 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2497 result = yield self._device.omci_cc.send(frame)
2498 if not result.fields['omci_message'].fields['success_code']:
2499 self.logger.info('Self-Test Submitted Successfully',
2500 code=result.fields[
2501 'omci_message'].fields['success_code'])
2502 else:
2503 raise TestFailure('Test Failure: {}'.format(
2504 result.fields['omci_message'].fields['success_code']))
2505 except TimeoutError as e:
2506 self.deferred.errback(failure.Failure(e))
2507
2508 except Exception as e:
2509 self.logger.exception('perform-test-Error', e=e,
2510 class_id=self._entity_class,
2511 entity_id=self._entity_id)
2512 self.deferred.errback(failure.Failure(e))
2513
2514 */
2515
2516 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002518
mpagenko1cc3cb42020-07-27 15:24:38 +00002519 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2520 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2521 * 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 +05302522 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002523 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302524
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302526 // Breaking this part of code due to sca complexity
2527 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2528 return err
2529}
2530
2531func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002533 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534 if pMibUlFsm.Is(mib.UlStDisabled) {
2535 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2536 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2537 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302538 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002539 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302540 //Determine ONU status and start/re-start MIB Synchronization tasks
2541 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 if pDevEntry.IsNewOnu() {
2543 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2544 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2545 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002546 }
Himani Chawla4d908332020-08-31 12:30:20 +05302547 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002548 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2549 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2550 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302551 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002552 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002553 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002554 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002555 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 "device-id": dh.DeviceID})
2557 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002558 }
2559 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002560 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2561 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002562 }
2563 return nil
2564}
2565
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002566func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002567 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002568 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302570 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002571
mpagenko900ee4b2020-10-12 11:56:34 +00002572 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2573 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2574 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002575 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002578 // abort: system behavior is just unstable ...
2579 return err
2580 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002581 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302582 if !dh.GetDeviceTechProfOnReboot() {
2583 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2584 }
mpagenko900ee4b2020-10-12 11:56:34 +00002585
2586 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002587 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002589 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2591 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002592 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002594
2595 //TODO!!! remove existing traffic profiles
2596 /* from py code, if TP's exist, remove them - not yet implemented
2597 self._tp = dict()
2598 # Let TP download happen again
2599 for uni_id in self._tp_service_specific_task:
2600 self._tp_service_specific_task[uni_id].clear()
2601 for uni_id in self._tech_profile_download_done:
2602 self._tech_profile_download_done[uni_id].clear()
2603 */
2604
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002606
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002608
mpagenkoe4782082021-11-25 12:04:26 +00002609 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002610 // abort: system behavior is just unstable ...
2611 return err
2612 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002615 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002617 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2618 OperStatus: voltha.OperStatus_DISCOVERED,
2619 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002620 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002623 // abort: system behavior is just unstable ...
2624 return err
2625 }
akashreddykb03dde02025-12-02 10:53:18 +05302626 if dh.GetDeviceTechProfOnReboot() {
2627 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2628 if err := dh.StorePersistentData(ctx); err != nil {
2629 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2630 log.Fields{"device-id": dh.DeviceID, "err": err})
2631 }
2632 }
mpagenko3af1f032020-06-10 08:53:41 +00002633 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002635 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002636 return nil
2637}
2638
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002639func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002640 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2641 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2642 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2643 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002644 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002645
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302647 //VOL-5260: During race conditions when adoptDevice has not yet completed
2648 // and deleteDevice is issued , returning error will further prevent clean up
2649 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002650 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302651 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2652 logger.Error(ctx, errMsg)
2653 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002654 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002655 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002656 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002657 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 pDevEntry.MutexOnuImageStatus.RLock()
2659 if pDevEntry.POnuImageStatus != nil {
2660 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002661 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002663
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002664 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002665 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002666 }
2667 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002669 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002670 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002671 }
mpagenko101ac942021-11-16 15:01:29 +00002672 //stop any deviceHandler reconcile processing (if running)
2673 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002674 //port lock/unlock FSM's may be active
2675 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002676 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002677 }
2678 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002679 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002680 }
2681 //techProfile related PonAniConfigFsm FSM may be active
2682 if dh.pOnuTP != nil {
2683 // should always be the case here
2684 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 if dh.pOnuTP.PAniConfigFsm != nil {
2686 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2687 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002688 }
mpagenko900ee4b2020-10-12 11:56:34 +00002689 }
2690 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002691 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002692 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002694 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002695 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002696 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002697 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002698 } else {
2699 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002700 }
2701 }
2702 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302703
2704 dh.mutexCollectorFlag.Lock()
2705 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2706 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002707 // Stop collector routine
2708 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302709 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002710 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302711 dh.mutexCollectorFlag.Unlock()
2712
2713 dh.mutextAlarmManagerFlag.Lock()
2714 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2715 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302716 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302717 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302718 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302719 dh.mutextAlarmManagerFlag.Unlock()
2720
2721 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2722 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2723 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002724 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302725 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002726 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302727 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302728
Girish Gowdrae95687a2021-09-08 16:30:58 -07002729 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2730
mpagenko80622a52021-02-09 16:53:23 +00002731 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002733 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002734 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002735 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002736 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002737 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002738 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2739 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2740 // (even though it may also run into direct cancellation, a bit hard to verify here)
2741 // so don't set 'dh.upgradeCanceled = true' here!
2742 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2743 }
mpagenko38662d02021-08-11 09:45:19 +00002744 }
mpagenko80622a52021-02-09 16:53:23 +00002745
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002747 return nil
2748}
2749
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302750//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002751func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2752 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 +05302753
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002754 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002756 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002758 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002759 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002761
mpagenkoa40e99a2020-11-17 13:50:39 +00002762 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2763 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2764 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2765 * disable/enable toggling here to allow traffic
2766 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2767 * like the py comment says:
2768 * # start by locking all the unis till mib sync and initial mib is downloaded
2769 * # this way we can capture the port down/up events when we are ready
2770 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302771
mpagenkoa40e99a2020-11-17 13:50:39 +00002772 // Init Uni Ports to Admin locked state
2773 // *** should generate UniLockStateDone event *****
2774 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002776 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002778 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002779 }
2780}
2781
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302782//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002783func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2784 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302785 /* Mib download procedure -
2786 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2787 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002788 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002789 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002791 return
2792 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302794 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 if pMibDlFsm.Is(mib.DlStDisabled) {
2796 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2797 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 +05302798 // maybe try a FSM reset and then again ... - TODO!!!
2799 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002800 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302801 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2803 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302804 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002805 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302806 //Begin MIB data download (running autonomously)
2807 }
2808 }
2809 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002810 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002811 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302812 // maybe try a FSM reset and then again ... - TODO!!!
2813 }
2814 /***** Mib download started */
2815 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002816 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302817 }
2818}
2819
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302820//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302822 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002823 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2824 if pDevEntry == nil {
2825 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2826 return
2827 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002828 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002829 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002830 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002831 // update device info in core
2832 pDevEntry.MutexPersOnuConfig.RLock()
2833 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2834 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2835 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2836 pDevEntry.MutexPersOnuConfig.RUnlock()
2837 dh.logicalDeviceID = dh.DeviceID
2838 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2839 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2840 }
2841 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002842 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2843 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2844 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2845 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002846 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002847 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002848 ConnStatus: voltha.ConnectStatus_REACHABLE,
2849 OperStatus: voltha.OperStatus_ACTIVE,
2850 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302851 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002852 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302853 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302855 }
2856 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302857 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302859 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002860 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002861
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002862 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002863 var waitForOmciProcessor sync.WaitGroup
2864 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002865 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002866 go dh.StartCollector(ctx, &waitForOmciProcessor)
2867 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002868 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 if !dh.GetAlarmManagerIsRunning(ctx) {
2870 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002871 }
2872
Girish Gowdrae95687a2021-09-08 16:30:58 -07002873 // Start flow handler routines per UNI
2874 for _, uniPort := range dh.uniEntityMap {
2875 // only if this port was enabled for use by the operator at startup
2876 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2877 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2878 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2879 }
2880 }
2881 }
2882
Girish Gowdrae0140f02021-02-02 16:55:09 -08002883 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002885 // There is no way we should be landing here, but if we do then
2886 // there is nothing much we can do about this other than log error
2887 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2888 }
2889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002890 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002891
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892 pDevEntry.MutexPersOnuConfig.RLock()
2893 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2894 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302895 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002896 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002897 dh.mutexForDisableDeviceRequested.Lock()
2898 dh.disableDeviceRequested = true
2899 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002900 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002901 // reconcilement will be continued after ani config is done
2902 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002904 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002905 dh.mutexForDisableDeviceRequested.RLock()
2906 if !dh.disableDeviceRequested {
2907 if dh.pUnlockStateFsm == nil {
2908 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2909 } else { //UnlockStateFSM already init
2910 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2911 dh.runUniLockFsm(ctx, false)
2912 }
2913 dh.mutexForDisableDeviceRequested.RUnlock()
2914 } else {
2915 dh.mutexForDisableDeviceRequested.RUnlock()
2916 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002917 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302918 }
2919}
2920
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302921//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2923 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302926 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2927 if dh.GetDeviceTechProfOnReboot() {
2928 if dh.CheckForDeviceTechProf(ctx) {
2929 go dh.DeviceFlowConfigOnReboot(ctx)
2930 }
2931 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002933 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002934 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2935 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002936 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002938 return
2939 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 pDevEntry.MutexPersOnuConfig.Lock()
2941 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2942 pDevEntry.MutexPersOnuConfig.Unlock()
2943 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002944 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002946 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302947 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302948 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 +00002949 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002950 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302951
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002952 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302953
Himani Chawla26e555c2020-08-31 12:30:20 +05302954 }
2955}
2956
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302957//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002959 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002961
mpagenko44bd8362021-11-15 11:40:05 +00002962 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002963 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002965 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002966 OperStatus: voltha.OperStatus_UNKNOWN,
2967 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002968 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002970 }
2971
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "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.DrOmciAdminLock, 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.DisableUniPortStateUpdate(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 = true
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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002995 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002997 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002999 ConnStatus: voltha.ConnectStatus_REACHABLE,
3000 OperStatus: voltha.OperStatus_ACTIVE,
3001 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00003002 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00003004 }
3005
dbainbri4d3a0dc2020-12-02 00:33:42 +00003006 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00003008 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00003009 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00003010
3011 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003012 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003015 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003017 return
3018 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003019 pDevEntry.MutexPersOnuConfig.Lock()
3020 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
3021 pDevEntry.MutexPersOnuConfig.Unlock()
3022 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003023 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003024 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003025 }
mpagenko900ee4b2020-10-12 11:56:34 +00003026}
3027
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303028//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003029func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3030 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
3031 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003032 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003033 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00003034 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003035 OperStatus: voltha.OperStatus_FAILED,
3036 }); err != nil {
3037 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
3038 }
3039}
3040
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3042 if devEvent == cmn.OmciAniConfigDone {
3043 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003044 // attention: the device reason update is done based on ONU-UNI-Port related activity
3045 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003047 // 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 +00003048 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05303049 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003051 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
3052 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
3053 dh.mutexReconcilingFirstPassFlag.Lock()
3054 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303055 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003056 dh.reconcilingFirstPass = false
3057 go dh.ReconcileDeviceFlowConfig(ctx)
3058 }
3059 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003060 }
3061 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003063 // attention: the device reason update is done based on ONU-UNI-Port related activity
3064 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003066 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3067 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003068 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003069 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303070}
3071
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003072func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003074 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303075 // attention: the device reason update is done based on ONU-UNI-Port related activity
3076 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303077
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003078 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3079 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003080 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003081 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003082 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003083 }
3084 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003085 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003086 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003087 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003088 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303089 }
mpagenkof1fc3862021-02-16 10:09:52 +00003090
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003092 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003094 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003095 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003096 }
3097 } else {
3098 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003100 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303101}
3102
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303103// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303105 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003107 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003108 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003109 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003111 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003112 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003113 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003115 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003116 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003117 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003119 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003120 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003121 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003123 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003124 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003125 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003126 case cmn.UniEnableStateFailed:
3127 {
3128 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3129 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003130 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003131 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003133 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003135 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003136 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003137 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003139 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003140 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003141 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003142 default:
3143 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003144 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003145 }
3146 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003147}
3148
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003149func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003150 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003151 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303152 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003153 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003154 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003155 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303156 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003158 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003159 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 +00003160 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003161 //store UniPort with the System-PortNumber key
3162 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003163 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003164 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003166 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003167 } //error logging already within UniPort method
3168 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303169 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003170 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003171 }
3172 }
3173}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003175func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3176 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003177 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003179 return
3180 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003181 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003182 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003183 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3184 for _, mgmtEntityID := range pptpInstKeys {
3185 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003186 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003187 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3188 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003189 }
3190 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003192 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003193 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003194 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3195 for _, mgmtEntityID := range veipInstKeys {
3196 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003198 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3199 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003200 }
3201 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003202 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003203 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003204 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003205 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3206 for _, mgmtEntityID := range potsInstKeys {
3207 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003209 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3210 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003211 }
3212 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003214 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003215 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003216 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003217 return
3218 }
3219
mpagenko2c3f6c52021-11-23 11:22:10 +00003220 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3221 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3222 // 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 -07003223 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3224 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3225 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003226 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3227 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303228 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003229 for i := 0; i < int(uniCnt); i++ {
3230 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003231 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003232 }
3233}
3234
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3236func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003237 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303238 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003239 // with following remark:
3240 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3241 // # load on the core
3242
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003243 // 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 +00003244
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003245 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003246 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3248 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303249 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003250 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003251 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003252 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003253 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003254 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003255 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003256 PortNo: port.PortNo,
3257 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003258 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003259 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 -04003260 }
3261 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003262 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303263 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003264 }
mpagenko3af1f032020-06-10 08:53:41 +00003265 }
3266 }
3267}
3268
3269// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3271 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003272 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3273 for uniNo, uniPort := range dh.uniEntityMap {
3274 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003275
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003276 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3277 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303278 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003280 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003281 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003282 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003283 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003284 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003285 PortNo: port.PortNo,
3286 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003287 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003288 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 -04003289 }
3290 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003291 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303292 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003293 }
3294
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003295 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003296 }
3297}
3298
3299// ONU_Active/Inactive announcement on system KAFKA bus
3300// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303301func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003302 var de voltha.DeviceEvent
3303 eventContext := make(map[string]string)
3304 //Populating event context
3305 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003306 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003307 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003308 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003309 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003310 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 +00003311 }
3312 oltSerialNumber := parentDevice.SerialNumber
3313
3314 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3315 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3316 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303317 eventContext["olt-serial-number"] = oltSerialNumber
3318 eventContext["device-id"] = aDeviceID
3319 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003320 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003321 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3322 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003323 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3324 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003325 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3326 deviceEntry.MutexPersOnuConfig.RUnlock()
3327 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003329 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3330 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3331 } else {
3332 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3333 log.Fields{"device-id": aDeviceID})
3334 return
3335 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003336
3337 /* Populating device event body */
3338 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303339 de.ResourceId = aDeviceID
3340 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003341 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3342 de.Description = fmt.Sprintf("%s Event - %s - %s",
3343 cEventObjectType, cOnuActivatedEvent, "Raised")
3344 } else {
3345 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3346 de.Description = fmt.Sprintf("%s Event - %s - %s",
3347 cEventObjectType, cOnuActivatedEvent, "Cleared")
3348 }
3349 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303350 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003351 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303352 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003353 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303354 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303355 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003356}
3357
Himani Chawla4d908332020-08-31 12:30:20 +05303358// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303360 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003361 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303362 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003363 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003364 sFsmName = "LockStateFSM"
3365 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003367 sFsmName = "UnLockStateFSM"
3368 }
mpagenko3af1f032020-06-10 08:53:41 +00003369
bseenivacfcd8f72026-01-30 21:06:49 +05303370 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00003371 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003372 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003373 return
3374 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003376 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303377 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003378 dh.pLockStateFsm = pLSFsm
3379 } else {
3380 dh.pUnlockStateFsm = pLSFsm
3381 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003382 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003383 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003385 }
3386}
3387
3388// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003389func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003390 /* Uni Port lock/unlock procedure -
3391 ***** should run via 'adminDone' state and generate the argument requested event *****
3392 */
3393 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303394 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003395 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003396 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3397 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3399 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003400 }
3401 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003403 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3404 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003405 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3406 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003407 }
3408 }
3409 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3411 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003412 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003413 // maybe try a FSM reset and then again ... - TODO!!!
3414 } else {
3415 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003416 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003417 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003418 }
3419 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003420 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003422 // maybe try a FSM reset and then again ... - TODO!!!
3423 }
3424 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003426 // maybe try a FSM reset and then again ... - TODO!!!
3427 }
3428}
3429
mpagenko80622a52021-02-09 16:53:23 +00003430// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003431// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303432//
3433//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003434func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303435 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003436 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003437 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003438 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303440 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003441 }
bseeniva0b4286b2026-01-30 13:05:42 +05303442 fsmCtx := log.WithSpanFromContext(context.Background(), ctx)
3443 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(fsmCtx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003444 sFsmName, chUpgradeFsm)
3445 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003447 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3449 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003450 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003451 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303452 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003453 }
mpagenko59862f02021-10-11 08:53:18 +00003454 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003455 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3456 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003457 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3458 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003459 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003461 } else {
3462 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003464 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303465 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003466 }
3467 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003468 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003469 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303470 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003471 }
3472 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303474 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003475 }
3476 return nil
3477}
3478
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3480func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003481 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003482 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003483 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003484 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3485 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003486 dh.pLastUpgradeImageState = apImageState
3487 dh.lockUpgradeFsm.Unlock()
3488 //signal upgradeFsm removed using non-blocking channel send
3489 select {
3490 case dh.upgradeFsmChan <- struct{}{}:
3491 default:
3492 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003494 }
mpagenko80622a52021-02-09 16:53:23 +00003495}
3496
mpagenko15ff4a52021-03-02 10:09:20 +00003497// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3498func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003500 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003502 return
3503 }
3504
3505 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003506 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003507 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003508 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3509 dh.lockUpgradeFsm.RUnlock()
3510 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3511 return
3512 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003514 if pUpgradeStatemachine != nil {
3515 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3516 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003517 UpgradeState := pUpgradeStatemachine.Current()
3518 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3519 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3520 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003521 // 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 +00003522 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003523 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3524 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003525 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003526 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003528 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3529 dh.upgradeCanceled = true
3530 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3531 }
mpagenko15ff4a52021-03-02 10:09:20 +00003532 return
3533 }
mpagenko59862f02021-10-11 08:53:18 +00003534 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3536 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003537 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003539 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3540 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003541 return
3542 }
3543 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003544 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003545 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3547 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003548 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3549 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003550 return
3551 }
3552 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003553 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003554 }
3555 } else {
3556 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 +00003557 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003558 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3559 dh.upgradeCanceled = true
3560 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3561 }
mpagenko1f8e8822021-06-25 14:10:21 +00003562 }
mpagenko15ff4a52021-03-02 10:09:20 +00003563 return
3564 }
mpagenko59862f02021-10-11 08:53:18 +00003565 dh.lockUpgradeFsm.RUnlock()
3566 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3567 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003568 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3569 dh.upgradeCanceled = true
3570 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3571 }
mpagenko59862f02021-10-11 08:53:18 +00003572 return
3573 }
3574 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3575 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3576 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3577 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3578 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3579 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3580 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003581 }
mpagenko15ff4a52021-03-02 10:09:20 +00003582 }
3583 }
3584 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003585 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003586 }
mpagenko59862f02021-10-11 08:53:18 +00003587 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003588}
3589
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303590// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003591func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003592
3593 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003595 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003596 kvbackend := &db.Backend{
3597 Client: dh.pOpenOnuAc.kvClient,
3598 StoreType: dh.pOpenOnuAc.KVStoreType,
3599 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003600 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003601 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3602 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003603
mpagenkoaf801632020-07-03 10:00:42 +00003604 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003605}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303606
3607//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003608func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303609 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003610
mpagenkodff5dda2020-08-28 11:52:01 +00003611 for _, field := range flow.GetOfbFields(apFlowItem) {
3612 switch field.Type {
3613 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3614 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003615 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003616 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3617 }
mpagenko01e726e2020-10-23 09:45:29 +00003618 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003619 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3620 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303621 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003622 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303623 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3624 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003625 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3626 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003627 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303629 return
mpagenkodff5dda2020-08-28 11:52:01 +00003630 }
3631 }
mpagenko01e726e2020-10-23 09:45:29 +00003632 */
mpagenkodff5dda2020-08-28 11:52:01 +00003633 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3634 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303635 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003636 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303637 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3638 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303639 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003640 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303642 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003643 }
3644 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3645 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303646 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003647 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303648 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003649 }
3650 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3651 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003652 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003653 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3654 }
3655 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3656 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003657 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003658 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3659 }
3660 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3661 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003663 "IPv4-DST": field.GetIpv4Dst()})
3664 }
3665 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3666 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003667 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003668 "IPv4-SRC": field.GetIpv4Src()})
3669 }
3670 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3671 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003672 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003673 "Metadata": field.GetTableMetadata()})
3674 }
3675 /*
3676 default:
3677 {
3678 //all other entires ignored
3679 }
3680 */
3681 }
3682 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303683}
mpagenkodff5dda2020-08-28 11:52:01 +00003684
khenaidoo7d3c5582021-08-11 18:09:44 -04003685func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003686 for _, action := range flow.GetActions(apFlowItem) {
3687 switch action.Type {
3688 /* not used:
3689 case of.OfpActionType_OFPAT_OUTPUT:
3690 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003691 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003692 "Output": action.GetOutput()})
3693 }
3694 */
3695 case of.OfpActionType_OFPAT_PUSH_VLAN:
3696 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003697 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003698 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3699 }
3700 case of.OfpActionType_OFPAT_SET_FIELD:
3701 {
3702 pActionSetField := action.GetSetField()
3703 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003704 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003705 "OxcmClass": pActionSetField.Field.OxmClass})
3706 }
3707 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303708 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303710 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003711 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303712 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003713 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303714 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003715 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003716 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003717 "Type": pActionSetField.Field.GetOfbField().Type})
3718 }
3719 }
3720 /*
3721 default:
3722 {
3723 //all other entires ignored
3724 }
3725 */
3726 }
3727 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303728}
3729
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303730// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003732 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303733 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3734 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303735 var loSetPcp uint8
3736 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303737 var loIPProto uint32
3738 /* the TechProfileId is part of the flow Metadata - compare also comment within
3739 * OLT-Adapter:openolt_flowmgr.go
3740 * Metadata 8 bytes:
3741 * Most Significant 2 Bytes = Inner VLAN
3742 * Next 2 Bytes = Tech Profile ID(TPID)
3743 * Least Significant 4 Bytes = Port ID
3744 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3745 * subscriber related flows.
3746 */
3747
dbainbri4d3a0dc2020-12-02 00:33:42 +00003748 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303749 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003750 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003751 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003752 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303753 }
mpagenko551a4d42020-12-08 18:09:20 +00003754 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003755 loCookie := apFlowItem.GetCookie()
3756 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303757 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303759 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303760
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303761 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003762 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303763 if loIPProto == 2 {
3764 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3765 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003766 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303768 return nil
3769 }
mpagenko01e726e2020-10-23 09:45:29 +00003770 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003771 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003772
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303773 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3774 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003775 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003777 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3778 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3779 //TODO!!: Use DeviceId within the error response to rwCore
3780 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003781 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003782 }
3783 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003784 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003785 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303786 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3787 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3788 loSetVlan = loMatchVlan
3789 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 +00003790 } else {
3791 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3792 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3793 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303794 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003795 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003796 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003797 }
mpagenko9a304ea2020-12-16 15:54:01 +00003798
khenaidoo42dcdfd2021-10-19 17:34:12 -04003799 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003800 if apFlowMetaData != nil {
3801 meter = apFlowMetaData.Meters[0]
3802 }
mpagenkobc4170a2021-08-17 16:42:10 +00003803 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3804 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3805 // when different rules are requested concurrently for the same uni
3806 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3807 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3808 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003809 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3810 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003811 //SetUniFlowParams() may block on some rule that is suspended-to-add
3812 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003813 // Also the error is returned to caller via response channel
3814 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303815 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003816 dh.lockVlanConfig.RUnlock()
3817 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003818 return
mpagenkodff5dda2020-08-28 11:52:01 +00003819 }
mpagenkobc4170a2021-08-17 16:42:10 +00003820 dh.lockVlanConfig.RUnlock()
3821 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003822 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303823 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003824 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003825 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003826 if err != nil {
3827 *respChan <- err
3828 }
mpagenko01e726e2020-10-23 09:45:29 +00003829}
3830
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303831// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003832func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003833 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3834 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3835 //no extra check is done on the rule parameters
3836 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3837 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3838 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3839 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003840 // - 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 +00003841 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003842 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003843
3844 /* TT related temporary workaround - should not be needed anymore
3845 for _, field := range flow.GetOfbFields(apFlowItem) {
3846 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3847 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003849 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3850 if loIPProto == 2 {
3851 // 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 +00003852 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003854 return nil
3855 }
3856 }
3857 } //for all OfbFields
3858 */
3859
mpagenko9a304ea2020-12-16 15:54:01 +00003860 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003861 dh.lockVlanConfig.RLock()
3862 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3864 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003865 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3866 return
mpagenko01e726e2020-10-23 09:45:29 +00003867 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003868 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003869 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003870 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003871 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003872 // Push response on the response channel
3873 if respChan != nil {
3874 // 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
3875 select {
3876 case *respChan <- nil:
3877 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3878 default:
3879 }
3880 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003882}
3883
Himani Chawla26e555c2020-08-31 12:30:20 +05303884// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003885// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003886// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003887func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303888 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 +05303889 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003890
bseenivacfcd8f72026-01-30 21:06:49 +05303891 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkodff5dda2020-08-28 11:52:01 +00003892 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003893 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3894 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003895 }
3896
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303897 if dh.pDeviceStateFsm.Current() == devStDown {
3898 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3899 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3900 }
3901
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3903 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303904 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003905 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003906 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3907 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3909 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003910 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003911 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3912 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003913 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3914 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003916 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303917 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003918 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003919 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3920 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003921 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003922 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003923 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3924 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003925 }
3926 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003927 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928 "device-id": dh.DeviceID})
3929 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003930 }
3931 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003932 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003933 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3934 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003935 }
3936 return nil
3937}
3938
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303939// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003940// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003941func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003942 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003944 for _, uniPort := range dh.uniEntityMap {
3945 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003946 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003947 pCurrentUniPort = uniPort
3948 break //found - end search loop
3949 }
3950 }
3951 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003952 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003953 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003954 return
3955 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003957}
3958
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303959// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003960func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003961 //TODO!! verify and start pending flow configuration
3962 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3963 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303964 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003965 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003966 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003967 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003968 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003969 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003970 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003971 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003972 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3974 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003975 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003976 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003977 } else {
3978 /***** UniVlanConfigFsm continued */
3979 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3981 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003982 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003983 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3984 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003985 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003986 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003987 } else {
3988 /***** UniVlanConfigFsm continued */
3989 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003990 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3991 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003992 }
mpagenkodff5dda2020-08-28 11:52:01 +00003993 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003994 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3996 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003997 }
3998 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003999 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 +00004000 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
4001 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00004002 }
4003 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004004 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004006 }
mpagenkof1fc3862021-02-16 10:09:52 +00004007 } else {
4008 dh.lockVlanConfig.RUnlock()
4009 }
mpagenkodff5dda2020-08-28 11:52:01 +00004010}
4011
Akash Soni3de0e062024-12-11 16:37:26 +05304012// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
4013func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
4014 dh.lockVlanConfig.Lock()
4015 defer dh.lockVlanConfig.Unlock()
4016
4017 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
4018 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
4019 if pVlanFilterStatemachine != nil {
4020 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4021 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
4022 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
4023 })
4024 } else {
4025 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
4026 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
4027 })
4028 }
4029 } else {
4030 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
4031 "device-id": dh.DeviceID, "UniPort": uniID,
4032 })
4033 }
4034 } else {
4035 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
4036 "device-id": dh.DeviceID, "UniPort": uniID,
4037 })
4038 }
4039}
4040
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304041// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00004042// 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 +00004043func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004044 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004045 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004046 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00004047 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00004049 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00004050}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004051
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304052// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004053func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00004054 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
4055 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
4056 // obviously then parallel processing on the cancel must be avoided
4057 // deadline context to ensure completion of background routines waited for
4058 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4059 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4060 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304061 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004062
Akash Soni840f8d62024-12-11 19:37:06 +05304063 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4064 if err != nil {
4065 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4066 return err
4067 }
4068 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004069}
4070
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304071// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4072// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004073func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4074 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004075
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004076 if dh.IsReconciling() {
bseeniva8c4547f2026-01-30 16:30:30 +05304077 logger.Debug(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004078 return nil
4079 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004080 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004081
bseenivacfcd8f72026-01-30 21:06:49 +05304082 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004083 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004084 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4085 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004086 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004088
mpagenkof1fc3862021-02-16 10:09:52 +00004089 if aWriteToKvStore {
4090 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4091 }
4092 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004093}
4094
dbainbri4d3a0dc2020-12-02 00:33:42 +00004095func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004096 defer cancel() //ensure termination of context (may be pro forma)
4097 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004098 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004099 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004100}
4101
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304102// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4103//
4104// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004105func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4106 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4107 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4108 dh.mutexDeviceReason.Lock()
4109 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004110 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004111 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004112 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004113 DeviceId: dh.DeviceID,
4114 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004115 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004116 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004117 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004118 return err
4119 }
mpagenkoe4782082021-11-25 12:04:26 +00004120 } else {
4121 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 +00004122 }
mpagenkoe4782082021-11-25 12:04:26 +00004123 dh.deviceReason = deviceReason
4124 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4125 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004126 return nil
4127}
4128
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004129func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
bseenivacfcd8f72026-01-30 21:06:49 +05304130 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004131 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4133 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004134 }
mpagenkof1fc3862021-02-16 10:09:52 +00004135 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004136}
4137
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304138func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4139 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4140 if pDevEntry != nil {
4141 pDevEntry.MutexPersOnuConfig.Lock()
4142 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4143 pDevEntry.MutexPersOnuConfig.Unlock()
4144 } else {
4145 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4146 }
4147}
4148
4149func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4150 rebootFlag := false
4151 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4152 if pDevEntry != nil {
4153 pDevEntry.MutexPersOnuConfig.RLock()
4154 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4155 pDevEntry.MutexPersOnuConfig.RUnlock()
4156 } else {
4157 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4158 }
4159 return rebootFlag
4160}
4161
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004162// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004163// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004164func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4165 dh.lockDevice.RLock()
4166 defer dh.lockDevice.RUnlock()
4167 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004168 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004169 }
4170 return 0, errors.New("error-fetching-uni-port")
4171}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004172
4173// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004174func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4175 var errorsList []error
4176 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 -08004177
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004178 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4179 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4180 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4181
4182 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4183 // successfully.
4184 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4185 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4186 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004187 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 -08004188 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004189 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004190 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004191 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004192}
4193
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004194func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4195 var err error
4196 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004197 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004198
4199 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004200 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004201 errorsList = append(errorsList, err)
4202 }
4203 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004204 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004205
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004206 return errorsList
4207}
4208
4209func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4210 var err error
4211 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004212 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004213 // Check if group metric related config is updated
4214 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004215 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4216 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4217 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004218
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004219 if ok && m.Frequency != v.GroupFreq {
4220 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004221 errorsList = append(errorsList, err)
4222 }
4223 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004224 if ok && m.Enabled != v.Enabled {
4225 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004226 errorsList = append(errorsList, err)
4227 }
4228 }
4229 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004230 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004231 return errorsList
4232}
4233
4234func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4235 var err error
4236 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004237 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004238 // Check if standalone metric related config is updated
4239 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004240 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4241 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4242 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004243
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004244 if ok && m.Frequency != v.SampleFreq {
4245 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004246 errorsList = append(errorsList, err)
4247 }
4248 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004249 if ok && m.Enabled != v.Enabled {
4250 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004251 errorsList = append(errorsList, err)
4252 }
4253 }
4254 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004255 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004256 return errorsList
4257}
4258
4259// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004260func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004261 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304262 dh.RLockMutexDeletionInProgressFlag()
4263 if dh.GetDeletionInProgress() {
4264 logger.Warnw(ctx, "Device deletion in progress - avoid starting metrics collector routine", log.Fields{"device-id": dh.device.Id})
4265 dh.RUnlockMutexDeletionInProgressFlag()
4266 return
4267 }
4268 // Set collectorIsRunning flag to true while still holding deviceDeletionFlag lock,
4269 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the collector routine if this flag is not yet set
4270 dh.setCollectorIsRunning(true)
4271 dh.RUnlockMutexDeletionInProgressFlag()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004272
4273 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004274 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304275 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004276 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004277 // Initialize the next metric collection time.
4278 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4279 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004280 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304281 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4282 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004283 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304284
Girish Gowdrae09a6202021-01-12 18:10:59 -08004285 select {
4286 case <-dh.stopCollector:
4287 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004288 // Stop the L2 PM FSM
4289 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004290 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4291 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4292 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004293 }
4294 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004295 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004296 }
4297 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004298 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4299 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004300 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004301 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4302 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004303 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004304
Girish Gowdrae09a6202021-01-12 18:10:59 -08004305 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304306 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004307 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4308 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4309 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4310 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004311 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004312 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4313 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004314 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004315 } else {
4316 if dh.pmConfigs.Grouped { // metrics are managed as a group
4317 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004318 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004319
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004320 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4321 // 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 -08004322 // 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 +00004323 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4324 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004325 }
4326 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004327 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4328 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4329 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4330 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004331 }
4332 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004333 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004334
4335 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004336 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4337 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4338 // 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 -08004339 // 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 +00004340 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004341 prevInternal := g.NextCollectionInterval
4342 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004343 }
4344 }
4345 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004346 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4347 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4348 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004349 prevInternal := m.NextCollectionInterval
4350 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004351 }
4352 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004353 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004354 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004355 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004356 } */
4357 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004358 }
4359 }
4360}
kesavandfdf77632021-01-26 23:40:33 -05004361
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304362//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304363func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4364
4365 singleValResp := extension.SingleSetValueResponse{
4366 Response: &extension.SetValueResponse{
4367 Status: extension.SetValueResponse_OK,
4368 },
4369 }
4370
4371 return &singleValResp
4372}
4373
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004374func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004376 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4377 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004378}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004379
Himani Chawla43f95ff2021-06-03 00:24:12 +05304380func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4381 if dh.pOnuMetricsMgr == nil {
4382 return &extension.SingleGetValueResponse{
4383 Response: &extension.GetValueResponse{
4384 Status: extension.GetValueResponse_ERROR,
4385 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4386 },
4387 }
4388 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304389 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304390 return resp
4391}
4392
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004393func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4394
4395 var err error
4396 var pDevOmciCC *cmn.OmciCC
4397 if dh.pOnuOmciDevice == nil {
4398 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4399 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4400 } else {
4401 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4402 if pDevOmciCC == nil {
4403 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4404 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4405 }
4406 }
4407 if err != nil {
4408 return &extension.SingleGetValueResponse{
4409 Response: &extension.GetValueResponse{
4410 Status: extension.GetValueResponse_ERROR,
4411 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4412 },
4413 },
4414 err
4415 }
4416 return pDevOmciCC.GetOmciCounters(), nil
4417}
4418
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304419//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004420func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4421 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004422 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004423 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004424 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004425}
4426
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004427func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004428 var pAdapterFsm *cmn.AdapterFsm
4429 //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 +00004430 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004431 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004432 {
mpagenkofbf577d2021-10-12 11:44:33 +00004433 if dh.pOnuOmciDevice != nil {
4434 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4435 } else {
4436 return true //FSM not active - so there is no activity on omci
4437 }
mpagenkof1fc3862021-02-16 10:09:52 +00004438 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004439 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004440 {
mpagenkofbf577d2021-10-12 11:44:33 +00004441 if dh.pOnuOmciDevice != nil {
4442 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4443 } else {
4444 return true //FSM not active - so there is no activity on omci
4445 }
mpagenkof1fc3862021-02-16 10:09:52 +00004446 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004447 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004448 {
mpagenkofbf577d2021-10-12 11:44:33 +00004449 if dh.pLockStateFsm != nil {
4450 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4451 } else {
4452 return true //FSM not active - so there is no activity on omci
4453 }
mpagenkof1fc3862021-02-16 10:09:52 +00004454 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004455 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004456 {
mpagenkofbf577d2021-10-12 11:44:33 +00004457 if dh.pUnlockStateFsm != nil {
4458 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4459 } else {
4460 return true //FSM not active - so there is no activity on omci
4461 }
mpagenkof1fc3862021-02-16 10:09:52 +00004462 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004463 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004464 {
mpagenkofbf577d2021-10-12 11:44:33 +00004465 if dh.pOnuMetricsMgr != nil {
4466 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004467 } else {
4468 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004469 }
4470 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004471 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004472 {
4473 dh.lockUpgradeFsm.RLock()
4474 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004475 if dh.pOnuUpradeFsm != nil {
4476 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4477 } else {
4478 return true //FSM not active - so there is no activity on omci
4479 }
mpagenko80622a52021-02-09 16:53:23 +00004480 }
mpagenkof1fc3862021-02-16 10:09:52 +00004481 default:
4482 {
4483 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004484 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004485 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004486 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004487 }
mpagenkofbf577d2021-10-12 11:44:33 +00004488 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4489 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4490 }
4491 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004492}
4493
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004494func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4495 for _, v := range dh.pOnuTP.PAniConfigFsm {
4496 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004497 return false
4498 }
4499 }
4500 return true
4501}
4502
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304503//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004504func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004505 dh.lockVlanConfig.RLock()
4506 defer dh.lockVlanConfig.RUnlock()
4507 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004508 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004509 return false
4510 }
4511 }
4512 return true //FSM not active - so there is no activity on omci
4513}
4514
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304515//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004516func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4517 dh.lockVlanConfig.RLock()
4518 defer dh.lockVlanConfig.RUnlock()
4519 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004520 if v.PAdaptFsm.PFsm != nil {
4521 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004522 return true //there is at least one VLAN FSM with some active configuration
4523 }
4524 }
4525 }
4526 return false //there is no VLAN FSM with some active configuration
4527}
4528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004529func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004530 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4531 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4532 return false
4533 }
4534 }
4535 // a further check is done to identify, if at least some data traffic related configuration exists
4536 // 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])
4537 return dh.checkUserServiceExists(ctx)
4538}
4539
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004540func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304541 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 +00004542 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004543 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004544 // TODO: fatal error reset ONU, delete deviceHandler!
4545 return
4546 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004547 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4548 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004549}
4550
4551func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4552 dh.mutexCollectorFlag.Lock()
4553 dh.collectorIsRunning = flagValue
4554 dh.mutexCollectorFlag.Unlock()
4555}
4556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004557func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004558 dh.mutexCollectorFlag.RLock()
4559 flagValue := dh.collectorIsRunning
4560 dh.mutexCollectorFlag.RUnlock()
4561 return flagValue
4562}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304563
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304564func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4565 dh.mutextAlarmManagerFlag.Lock()
4566 dh.alarmManagerIsRunning = flagValue
4567 dh.mutextAlarmManagerFlag.Unlock()
4568}
4569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004570func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304571 dh.mutextAlarmManagerFlag.RLock()
4572 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004573 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304574 dh.mutextAlarmManagerFlag.RUnlock()
4575 return flagValue
4576}
4577
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004578func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004579 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304580 dh.RLockMutexDeletionInProgressFlag()
4581 if dh.GetDeletionInProgress() {
4582 logger.Warnw(ctx, "Device deletion in progress - avoid starting alarm manager", log.Fields{"device-id": dh.DeviceID})
4583 dh.RUnlockMutexDeletionInProgressFlag()
4584 return
4585 }
4586 // Set alarmManagerIsRunning flag to true while still holding deviceDeletionFlag lock,
4587 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the alarm manager if this flag is not yet set
4588 dh.setAlarmManagerIsRunning(true)
4589
4590 dh.RUnlockMutexDeletionInProgressFlag()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304591
4592 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004593 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304594 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304595 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304596 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004597 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4598 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304599 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304600 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004601 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4602 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304603 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304604 }
4605}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004606
Girish Gowdrae95687a2021-09-08 16:30:58 -07004607func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4608 dh.mutexFlowMonitoringRoutineFlag.Lock()
4609 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004610 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004611 dh.isFlowMonitoringRoutineActive[uniID] = flag
4612}
4613
4614func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4615 dh.mutexFlowMonitoringRoutineFlag.RLock()
4616 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4617 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004618 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304619 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4620 return dh.isFlowMonitoringRoutineActive[uniID]
4621 }
4622 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004623}
4624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004625func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304626 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004627
Maninder7961d722021-06-16 22:10:28 +05304628 connectStatus := voltha.ConnectStatus_UNREACHABLE
4629 operState := voltha.OperStatus_UNKNOWN
4630
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004631 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004632 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004633 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004634 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004635 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004636 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304637 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004638 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4639 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4640 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4641 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4642 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4643 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4644 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4645 // However, a later refactoring of the functionality remains unaffected.
4646 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004647 if success {
bseenivacfcd8f72026-01-30 21:06:49 +05304648 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304649 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004650 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304651 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004652 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304653 switch onuDevEntry.SOnuPersistentData.PersOperState {
4654 case "up":
Maninderb5187552021-03-23 22:23:42 +05304655 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004656 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4657 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304658 operState = voltha.OperStatus_ACTIVE
4659 } else {
4660 operState = voltha.OperStatus_ACTIVATING
4661 }
4662 }
mgoudad611f4c2025-10-30 14:49:27 +05304663 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304664 operState = voltha.OperStatus_DISCOVERED
4665 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004666 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004667 logger.Debugw(ctx, "Core DeviceStateUpdate",
4668 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304669 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304670 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004671 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004672 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004673 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004674 ConnStatus: connectStatus,
4675 OperStatus: operState,
4676 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304677 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004678 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304679 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004680 } else {
Maninderb5187552021-03-23 22:23:42 +05304681 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004682 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304683
bseenivacfcd8f72026-01-30 21:06:49 +05304684 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304685 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004686 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004687 } else {
4688 onuDevEntry.MutexPersOnuConfig.RLock()
4689 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4690 connectStatus = voltha.ConnectStatus_REACHABLE
4691 }
4692 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304693 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004694 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004695 }
mpagenko101ac942021-11-16 15:01:29 +00004696 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004697 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004698 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004699 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304700
bseenivacfcd8f72026-01-30 21:06:49 +05304701 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304702 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004703 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004704 } else {
4705 onuDevEntry.MutexPersOnuConfig.RLock()
4706 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4707 connectStatus = voltha.ConnectStatus_REACHABLE
4708 }
4709 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304710 }
4711
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004712 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304713
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004714 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004715 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004716 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004717 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004718 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004719
bseenivacfcd8f72026-01-30 21:06:49 +05304720 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004721 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4722 } else {
4723 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304724 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004725 onuDevEntry.MutexReconciledTpInstances.Unlock()
4726 }
bseeniva33968f02026-01-30 18:49:48 +05304727 dh.chReconcilingStopped <- struct{}{}
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004728 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004729 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004730 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304731 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004732 dh.reconciling = cSkipOnuConfigReconciling
4733 } else {
4734 dh.reconciling = cOnuConfigReconciling
4735 }
4736 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004737}
4738
mpagenko101ac942021-11-16 15:01:29 +00004739func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304740 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004741 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004742 dh.sendChReconcileFinished(success)
4743 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4744 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4745 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004746 } else {
mpagenko101ac942021-11-16 15:01:29 +00004747 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004748 }
4749}
4750
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004751func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004752 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004753 defer dh.mutexReconcilingFlag.RUnlock()
4754 return dh.reconciling != cNoReconciling
4755}
4756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004757func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004758 dh.mutexReconcilingFlag.RLock()
4759 defer dh.mutexReconcilingFlag.RUnlock()
4760 return dh.reconciling == cSkipOnuConfigReconciling
4761}
4762
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004763func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4764 dh.mutexReconcilingFirstPassFlag.Lock()
4765 dh.reconcilingFirstPass = value
4766 dh.mutexReconcilingFirstPassFlag.Unlock()
4767}
4768
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004769func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4770 dh.mutexReconcilingReasonUpdate.Lock()
4771 dh.reconcilingReasonUpdate = value
4772 dh.mutexReconcilingReasonUpdate.Unlock()
4773}
4774
4775func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4776 dh.mutexReconcilingReasonUpdate.RLock()
4777 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4778 return dh.reconcilingReasonUpdate
4779}
4780
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004781func (dh *deviceHandler) getDeviceReason() uint8 {
4782 dh.mutexDeviceReason.RLock()
4783 value := dh.deviceReason
4784 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004785 return value
4786}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004787
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004788func (dh *deviceHandler) GetDeviceReasonString() string {
4789 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004790}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004791
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004792func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004793 dh.mutexReadyForOmciConfig.Lock()
4794 dh.readyForOmciConfig = flagValue
4795 dh.mutexReadyForOmciConfig.Unlock()
4796}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004797func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004798 dh.mutexReadyForOmciConfig.RLock()
4799 flagValue := dh.readyForOmciConfig
4800 dh.mutexReadyForOmciConfig.RUnlock()
4801 return flagValue
4802}
Maninder7961d722021-06-16 22:10:28 +05304803
4804func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004805 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304806 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004807 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304808 }
4809
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004810 logger.Debugw(ctx, "Core DeviceStateUpdate",
4811 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004812 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004813 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004814 ConnStatus: connectStatus,
4815 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4816 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304817 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004818 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304819 }
bseeniva4714cee2026-01-30 16:21:47 +05304820 context := make(map[string]string)
4821 context["device-id"] = dh.DeviceID
4822 context["onu-serial-number"] = dh.device.SerialNumber
4823 context["parent-id"] = dh.parentID
4824
4825 deviceEvent := &voltha.DeviceEvent{
4826 ResourceId: dh.DeviceID,
4827 DeviceEventName: cmn.OnuReconcileFailed,
4828 Description: cmn.OnuReconcileFailedAbortedDesc,
4829 Context: context,
4830 }
4831 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4832 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
Maninder7961d722021-06-16 22:10:28 +05304833}
khenaidoo7d3c5582021-08-11 18:09:44 -04004834
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304835func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4836 if techProfInstLoadFailed {
4837 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4838 logger.Errorw(ctx, "unable to update device reason to core",
4839 log.Fields{"device-id": dh.DeviceID, "Err": err})
4840 }
4841 context := make(map[string]string)
4842 context["device-id"] = dh.DeviceID
4843 context["onu-serial-number"] = dh.device.SerialNumber
4844 context["parent-id"] = dh.parentID
4845
4846 // Send event on flow configuration failure so that corrective action can be triggered from NB
4847 deviceEvent := &voltha.DeviceEvent{
4848 ResourceId: dh.DeviceID,
4849 DeviceEventName: cmn.OnuFlowConfigFailed,
4850 Description: cmn.OnuFlowConfigFailedDesc,
4851 Context: context,
4852 }
4853 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4854 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4855 }
4856}
4857
khenaidoo7d3c5582021-08-11 18:09:44 -04004858/*
4859Helper functions to communicate with Core
4860*/
4861
4862func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4863 cClient, err := dh.coreClient.GetCoreServiceClient()
4864 if err != nil || cClient == nil {
4865 return nil, err
4866 }
4867 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4868 defer cancel()
4869 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304870 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004871}
4872
khenaidoo42dcdfd2021-10-19 17:34:12 -04004873func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) 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.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004881 logger.Debugw(subCtx, "device-updated-in-core",
4882 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004883 return err
4884}
4885
4886func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4887 cClient, err := dh.coreClient.GetCoreServiceClient()
4888 if err != nil || cClient == nil {
4889 return err
4890 }
4891 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4892 defer cancel()
4893 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004894 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4895 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004896 return err
4897}
4898
4899func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4900 cClient, err := dh.coreClient.GetCoreServiceClient()
4901 if err != nil || cClient == nil {
4902 return err
4903 }
4904 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4905 defer cancel()
4906 _, err = cClient.DeviceUpdate(subCtx, device)
4907 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4908 return err
4909}
4910
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004911func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004912 cClient, err := dh.coreClient.GetCoreServiceClient()
4913 if err != nil || cClient == nil {
4914 return err
4915 }
4916 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4917 defer cancel()
4918 _, err = cClient.PortCreated(subCtx, port)
4919 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4920 return err
4921}
4922
khenaidoo42dcdfd2021-10-19 17:34:12 -04004923func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004924 cClient, err := dh.coreClient.GetCoreServiceClient()
4925 if err != nil || cClient == nil {
4926 return err
4927 }
4928 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4929 defer cancel()
4930 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004931 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 -04004932 return err
4933}
4934
khenaidoo42dcdfd2021-10-19 17:34:12 -04004935func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004936 cClient, err := dh.coreClient.GetCoreServiceClient()
4937 if err != nil || cClient == nil {
4938 return err
4939 }
4940 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4941 defer cancel()
4942 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004943 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 -04004944 return err
4945}
4946
4947/*
4948Helper functions to communicate with parent adapter
4949*/
4950
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004951func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4952 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4953
4954 var request = ia.TechProfileInstanceRequestMessage{
4955 DeviceId: dh.DeviceID,
4956 TpInstancePath: aTpPath,
4957 ParentDeviceId: dh.parentID,
4958 ParentPonPort: dh.device.ParentPortNo,
4959 OnuId: dh.device.ProxyAddress.OnuId,
4960 UniId: uint32(aUniID),
4961 }
4962
4963 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004964 if err != nil || pgClient == nil {
4965 return nil, err
4966 }
4967 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4968 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004969 logger.Debugw(subCtx, "get-tech-profile-instance",
4970 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004971 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004972}
4973
Girish Gowdrae95687a2021-09-08 16:30:58 -07004974// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4975// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4976func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
bseeniva8c4547f2026-01-30 16:30:30 +05304977 logger.Debugw(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004978 dh.setFlowMonitoringIsRunning(uniID, true)
4979 for {
4980 select {
4981 // block on the channel to receive an incoming flow
4982 // process the flow completely before proceeding to handle the next flow
4983 case flowCb := <-dh.flowCbChan[uniID]:
4984 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304985 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004986 respChan := make(chan error)
4987 if flowCb.addFlow {
4988 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4989 } else {
4990 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4991 }
4992 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304993 select {
4994
4995 case msg := <-respChan:
4996 *flowCb.respChan <- msg
4997 // response sent successfully
4998 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4999 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
5000 case <-flowCb.ctx.Done():
5001 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
5002 // Optionally, you can handle cleanup or logging here
5003 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
5004 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
5005 if pVlanFilterStatemachine != nil {
5006
5007 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
5008 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
5009 log.Fields{"device-id": dh.DeviceID, "err": err})
5010
5011 }
5012
5013 }
5014 }
5015
5016 ctx2 := context.Background()
5017 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
5018 if metadata == 0 {
5019 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
5020 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5021 continue
5022 }
5023 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
5024
5025 if TpID == uint16(0) {
5026 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
5027 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5028 continue
5029 }
5030 if dh.pOnuTP != nil {
5031 // should always be the case here
5032 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
5033 if dh.pOnuTP.PAniConfigFsm != nil {
5034 uniTP := avcfg.UniTP{
5035 UniID: flowCb.uniPort.UniID,
5036 TpID: uint8(TpID),
5037 }
5038 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
5039 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
5040 }
5041 }
5042 }
5043
5044 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07005045 case <-dh.stopFlowMonitoringRoutine[uniID]:
5046 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
5047 dh.setFlowMonitoringIsRunning(uniID, false)
5048 return
5049 }
5050 }
5051}
5052
kesavand011d5162021-11-25 19:21:06 +05305053func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
5054 request.ParentDeviceId = dh.GetProxyAddressID()
5055 request.ChildDeviceId = dh.DeviceID
5056 request.ProxyAddress = dh.GetProxyAddress()
5057 request.ConnectStatus = common.ConnectStatus_REACHABLE
5058
5059 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5060 if err != nil || pgClient == nil {
5061 return err
5062 }
5063 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5064 defer cancel()
5065 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
5066 _, err = pgClient.ProxyOmciRequests(subCtx, request)
5067 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00005068 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
5069 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05305070 }
5071 return err
5072}
5073
khenaidoo42dcdfd2021-10-19 17:34:12 -04005074func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04005075 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5076 if err != nil || pgClient == nil {
5077 return err
5078 }
5079 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5080 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005081 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005082 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04005083 _, err = pgClient.ProxyOmciRequest(subCtx, request)
5084 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005085 if status.Code(err) == codes.Unavailable {
5086 dh.setOltAvailable(false)
5087 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005088 logger.Errorw(ctx, "omci-failure",
5089 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005090 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005091 }
5092 return err
5093}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005094
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005095func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
5096 // Check if there are additional TCONT instances necessary/available
5097 pDevEntry.MutexPersOnuConfig.Lock()
5098 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5099 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5100 pDevEntry.MutexPersOnuConfig.Unlock()
5101 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5102 logger.Debugw(ctx, "checking available TCONT instances",
5103 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5104 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5105 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5106 log.Fields{"device-id": dh.device.Id})
5107 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305108 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005109 }
5110 } else {
5111 pDevEntry.MutexPersOnuConfig.Unlock()
5112 }
5113 // Check if there are enough PrioQueue instances available
5114 if dh.pOnuTP != nil {
5115 var numberOfUsPrioQueueDbInsts int
5116
5117 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5118 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305119 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005120 numberOfUsPrioQueueDbInsts++
5121 }
5122 }
5123 // Check if there is an upstream PriorityQueue instance available for each Gem port
5124 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5125 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5126 log.Fields{"device-id": dh.DeviceID,
5127 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5128 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5129 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5130
5131 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5132 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5133 log.Fields{"device-id": dh.device.Id})
5134 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305135 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 +00005136 }
5137 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5138 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5139 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5140 } else {
5141 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5142 log.Fields{"device-id": dh.DeviceID})
5143 }
5144 return nil
5145}
5146
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005147// GetDeviceID - TODO: add comment
5148func (dh *deviceHandler) GetDeviceID() string {
5149 return dh.DeviceID
5150}
5151
5152// GetProxyAddressID - TODO: add comment
5153func (dh *deviceHandler) GetProxyAddressID() string {
5154 return dh.device.ProxyAddress.GetDeviceId()
5155}
5156
5157// GetProxyAddressType - TODO: add comment
5158func (dh *deviceHandler) GetProxyAddressType() string {
5159 return dh.device.ProxyAddress.GetDeviceType()
5160}
5161
5162// GetProxyAddress - TODO: add comment
5163func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5164 return dh.device.ProxyAddress
5165}
5166
5167// GetEventProxy - TODO: add comment
5168func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5169 return dh.EventProxy
5170}
5171
5172// GetOmciTimeout - TODO: add comment
5173func (dh *deviceHandler) GetOmciTimeout() int {
5174 return dh.pOpenOnuAc.omciTimeout
5175}
5176
5177// GetAlarmAuditInterval - TODO: add comment
5178func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5179 return dh.pOpenOnuAc.alarmAuditInterval
5180}
5181
5182// GetDlToOnuTimeout4M - TODO: add comment
5183func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5184 return dh.pOpenOnuAc.dlToOnuTimeout4M
5185}
5186
5187// GetUniEntityMap - TODO: add comment
5188func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5189 return &dh.uniEntityMap
5190}
5191
5192// GetPonPortNumber - TODO: add comment
5193func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5194 return &dh.ponPortNumber
5195}
5196
5197// GetUniVlanConfigFsm - TODO: add comment
5198func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005199 dh.lockVlanConfig.RLock()
5200 value := dh.UniVlanConfigFsmMap[uniID]
5201 dh.lockVlanConfig.RUnlock()
5202 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005203}
5204
5205// GetOnuAlarmManager - TODO: add comment
5206func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5207 return dh.pAlarmMgr
5208}
5209
5210// GetOnuMetricsManager - TODO: add comment
5211func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5212 return dh.pOnuMetricsMgr
5213}
5214
5215// GetOnuTP - TODO: add comment
5216func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5217 return dh.pOnuTP
5218}
5219
5220// GetBackendPathPrefix - TODO: add comment
5221func (dh *deviceHandler) GetBackendPathPrefix() string {
5222 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5223}
5224
5225// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305226func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005227 return dh.pOnuIndication
5228}
5229
5230// RLockMutexDeletionInProgressFlag - TODO: add comment
5231func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5232 dh.mutexDeletionInProgressFlag.RLock()
5233}
5234
5235// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5236func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5237 dh.mutexDeletionInProgressFlag.RUnlock()
5238}
5239
5240// GetDeletionInProgress - TODO: add comment
5241func (dh *deviceHandler) GetDeletionInProgress() bool {
5242 return dh.deletionInProgress
5243}
5244
5245// GetPmConfigs - TODO: add comment
5246func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5247 return dh.pmConfigs
5248}
5249
5250// GetDeviceType - TODO: add comment
5251func (dh *deviceHandler) GetDeviceType() string {
5252 return dh.DeviceType
5253}
5254
5255// GetLogicalDeviceID - TODO: add comment
5256func (dh *deviceHandler) GetLogicalDeviceID() string {
5257 return dh.logicalDeviceID
5258}
5259
5260// GetDevice - TODO: add comment
5261func (dh *deviceHandler) GetDevice() *voltha.Device {
5262 return dh.device
5263}
5264
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005265func (dh *deviceHandler) setOltAvailable(value bool) {
5266 dh.mutexOltAvailable.Lock()
5267 dh.oltAvailable = value
5268 dh.mutexOltAvailable.Unlock()
5269}
5270
5271// IsOltAvailable - TODO: add comment
5272func (dh *deviceHandler) IsOltAvailable() bool {
5273 dh.mutexOltAvailable.RLock()
5274 defer dh.mutexOltAvailable.RUnlock()
5275 return dh.oltAvailable
5276}
5277
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005278// GetMetricsEnabled - TODO: add comment
5279func (dh *deviceHandler) GetMetricsEnabled() bool {
5280 return dh.pOpenOnuAc.MetricsEnabled
5281}
5282
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005283// GetExtendedOmciSupportEnabled - TODO: add comment
5284func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5285 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5286}
5287
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305288// GetExtendedOmciSupportEnabled - TODO: add comment
5289func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5290 return dh.pOpenOnuAc.skipOnuConfig
5291}
5292
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305293func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5294 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5295}
5296
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005297// InitPmConfigs - TODO: add comment
5298func (dh *deviceHandler) InitPmConfigs() {
5299 dh.pmConfigs = &voltha.PmConfigs{}
5300}
5301
5302// GetUniPortMask - TODO: add comment
5303func (dh *deviceHandler) GetUniPortMask() int {
5304 return dh.pOpenOnuAc.config.UniPortMask
5305}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005306
5307func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5308 tpPathFound := false
5309 for _, tpPath := range aTpPathMap {
5310 if tpPath != "" {
5311 tpPathFound = true
5312 }
5313 }
5314 return tpPathFound
5315}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005316
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305317func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5318 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5319 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5320 return resp
5321}
5322
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305323// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5324func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5325 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305326 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5327 return resp
5328}
5329
5330// getOnuFECStats - Get the GEM PM history data of the request ONT device
5331func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5332 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5333 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 +05305334 return resp
5335}
5336
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305337func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5338 return dh.deviceDeleteCommChan
5339}
5340
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005341// PrepareForGarbageCollection - remove references to prepare for garbage collection
5342func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5343 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5344
5345 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5346 // first let the objects rest for some time to give all asynchronously started
5347 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005348 time.Sleep(2 * time.Second)
5349
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005350 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005351
5352 if dh.pOnuTP != nil {
5353 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5354 }
5355 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005356 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5357 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005358 select {
5359 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5360 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5361 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5362 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005363 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005364 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005365 }
5366 if dh.pAlarmMgr != nil {
5367 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5368 }
5369 if dh.pSelfTestHdlr != nil {
5370 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5371 }
5372 if dh.pLockStateFsm != nil {
5373 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5374 }
5375 if dh.pUnlockStateFsm != nil {
5376 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5377 }
5378 if dh.pOnuUpradeFsm != nil {
5379 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5380 }
5381 if dh.pOnuOmciDevice != nil {
5382 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5383 }
5384 for k, v := range dh.UniVlanConfigFsmMap {
5385 v.PrepareForGarbageCollection(ctx, aDeviceID)
5386 delete(dh.UniVlanConfigFsmMap, k)
5387 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305388 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005389 dh.pOnuOmciDevice = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305390 dh.lockDevice.Lock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005391 dh.pOnuTP = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305392 dh.lockDevice.Unlock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005393 dh.pOnuMetricsMgr = nil
5394 dh.pAlarmMgr = nil
5395 dh.pSelfTestHdlr = nil
5396 dh.pLockStateFsm = nil
5397 dh.pUnlockStateFsm = nil
5398 dh.pOnuUpradeFsm = nil
5399}