blob: 2c5a58f34d1232a09d41295901ae6c942085e2fa [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo42dcdfd2021-10-19 17:34:12 -040050 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040051 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
52 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000055 "google.golang.org/grpc/codes"
56 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057)
58
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko101ac942021-11-16 15:01:29 +000060 //constants for reconcile flow check channel
61 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
62 cWaitReconcileFlowAbortOnError = 0xFFFE
63 cWaitReconcileFlowNoActivity = 0xFFFF
64)
65
66const (
67 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000068 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070
mpagenko1cc3cb42020-07-27 15:24:38 +000071const (
mpagenko44bd8362021-11-15 11:40:05 +000072 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
73 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
74 // as long as such is not available by the libraries - use this workaround
75 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
76)
77
78const (
mpagenko1cc3cb42020-07-27 15:24:38 +000079 // events of Device FSM
80 devEvDeviceInit = "devEvDeviceInit"
81 devEvGrpcConnected = "devEvGrpcConnected"
82 devEvGrpcDisconnected = "devEvGrpcDisconnected"
83 devEvDeviceUpInd = "devEvDeviceUpInd"
84 devEvDeviceDownInd = "devEvDeviceDownInd"
85)
86const (
87 // states of Device FSM
88 devStNull = "devStNull"
89 devStDown = "devStDown"
90 devStInit = "devStInit"
91 devStConnected = "devStConnected"
92 devStUp = "devStUp"
93)
94
praneeth nalmas5a0a5502022-12-23 15:57:00 +053095// Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096const (
Himani Chawla4d908332020-08-31 12:30:20 +053097 pon = voltha.EventSubCategory_PON
98 //olt = voltha.EventSubCategory_OLT
99 //ont = voltha.EventSubCategory_ONT
100 //onu = voltha.EventSubCategory_ONU
101 //nni = voltha.EventSubCategory_NNI
102 //service = voltha.EventCategory_SERVICE
103 //security = voltha.EventCategory_SECURITY
104 equipment = voltha.EventCategory_EQUIPMENT
105 //processing = voltha.EventCategory_PROCESSING
106 //environment = voltha.EventCategory_ENVIRONMENT
107 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000108)
109
110const (
111 cEventObjectType = "ONU"
112)
113const (
114 cOnuActivatedEvent = "ONU_ACTIVATED"
115)
116
mpagenkof1fc3862021-02-16 10:09:52 +0000117type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000119 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000122var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
123 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
124 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
125 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
128 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
129 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
130 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131}
132
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000133const (
134 cNoReconciling = iota
135 cOnuConfigReconciling
136 cSkipOnuConfigReconciling
137)
138
Girish Gowdrae95687a2021-09-08 16:30:58 -0700139// FlowCb is the flow control block containing flow add/delete information along with a response channel
140type FlowCb struct {
141 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142 flowItem *of.OfpFlowStats
143 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400144 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 respChan *chan error // channel to report the Flow handling error
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530146 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147}
148
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530149// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530151 EventProxy eventif.EventProxy
152
153 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000154
khenaidoo7d3c5582021-08-11 18:09:44 -0400155 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000156
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800157 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400158 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800159
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 pOpenOnuAc *OpenONUAC
161 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530162 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530163 deviceEntrySet chan bool //channel for DeviceEntry set event
164 pOnuOmciDevice *mib.OnuDeviceEntry
165 pOnuTP *avcfg.OnuUniTechProf
166 pOnuMetricsMgr *pmmgr.OnuMetricsManager
167 pAlarmMgr *almgr.OnuAlarmManager
168 pSelfTestHdlr *otst.SelfTestControlBlock
169 exitChannel chan int
170 pOnuIndication *oop.OnuIndication
171 pLockStateFsm *uniprt.LockStateFsm
172 pUnlockStateFsm *uniprt.LockStateFsm
173
174 stopCollector chan bool
175 stopAlarmManager chan bool
176 stopHeartbeatCheck chan bool
177 uniEntityMap cmn.OnuUniPortMap
178 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
179 pOnuUpradeFsm *swupg.OnuUpgradeFsm
180 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530181 chUniVlanConfigOnRebootDone chan uint16
182 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530183 pLastUpgradeImageState *voltha.ImageState
184 upgradeFsmChan chan struct{}
185
186 deviceDeleteCommChan chan bool
187 DeviceID string
188 DeviceType string
189 adminState string
190 logicalDeviceID string
191 ProxyAddressID string
192 ProxyAddressType string
193 parentID string
194
195 flowCbChan []chan FlowCb
196 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
197 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
198 reconcileExpiryComplete time.Duration
199 reconcileExpiryVlanConfig time.Duration
200 lockDevice sync.RWMutex
201 mutexDeviceReason sync.RWMutex
202 mutexCollectorFlag sync.RWMutex
203 mutextAlarmManagerFlag sync.RWMutex
204 lockVlanConfig sync.RWMutex
205 lockVlanAdd sync.RWMutex
206 lockUpgradeFsm sync.RWMutex
207 mutexReconcilingFlag sync.RWMutex
208 mutexReconcilingFirstPassFlag sync.RWMutex
209 mutexReconcilingReasonUpdate sync.RWMutex
210 mutexReadyForOmciConfig sync.RWMutex
211 mutexDeletionInProgressFlag sync.RWMutex
212 mutexFlowMonitoringRoutineFlag sync.RWMutex
213 mutexForDisableDeviceRequested sync.RWMutex
214 mutexOltAvailable sync.RWMutex
215 mutexKvStoreContext sync.Mutex
216 ponPortNumber uint32
217
218 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 //flowMgr *OpenOltFlowMgr
221 //eventMgr *OpenOltEventMgr
222 //resourceMgr *rsrcMgr.OpenOltResourceMgr
223
224 //discOnus sync.Map
225 //onus sync.Map
226 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530227 collectorIsRunning bool
228 alarmManagerIsRunning bool
229 upgradeCanceled bool
230 reconciling uint8
231 reconcilingFirstPass bool
232 reconcilingReasonUpdate bool
233 readyForOmciConfig bool
234 deletionInProgress bool
235 disableDeviceRequested bool // this flag identify ONU received disable request or not
236 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530239// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400240func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400242 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400244 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.DeviceType = cloned.Type
248 dh.adminState = "up"
249 dh.device = cloned
250 dh.pOpenOnuAc = adapter
251 dh.exitChannel = make(chan int, 1)
252 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000253 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000254 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530256 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530257 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopHeartbeatCheck = make(chan bool, 2)
259 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000261 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000262 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000263 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300265 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000266 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000267 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000268 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000269 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300270 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000271 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000272 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000273 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
274 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
275 if rECSeconds < 2 {
276 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
277 rECSeconds = 2
278 }
279 rEVCSeconds := rECSeconds / 2
280 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000281 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000282 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000283 dh.pLastUpgradeImageState = &voltha.ImageState{
284 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
285 Reason: voltha.ImageState_UNKNOWN_ERROR,
286 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
287 }
288 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530289 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800291 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
292 dh.pmConfigs = cloned.PmConfigs
293 } /* else {
294 // will be populated when onu_metrics_mananger is initialized.
295 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800296
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 // Device related state machine
298 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000301 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
302 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
303 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
304 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
305 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 },
307 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
309 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
310 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
311 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
312 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
313 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
314 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
315 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 },
317 )
mpagenkoaf801632020-07-03 10:00:42 +0000318
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 return &dh
320}
321
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322// start save the device to the data model
323func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000324 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000326 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327}
328
Himani Chawla4d908332020-08-31 12:30:20 +0530329/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332 logger.Debug("stopping-device-handler")
333 dh.exitChannel <- 1
334}
Himani Chawla4d908332020-08-31 12:30:20 +0530335*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000336
337// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530338// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530340// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530341func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400342 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000344 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530345
mpagenko1cc3cb42020-07-27 15:24:38 +0000346 if dh.pDeviceStateFsm.Is(devStNull) {
347 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000348 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000350 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800351 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
352 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800353 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400354 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000355 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800356 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800357 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000358 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360 }
361
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000362}
363
khenaidoo42dcdfd2021-10-19 17:34:12 -0400364func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000365 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 //assuming omci message content is hex coded!
367 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000370 */
bseenivacfcd8f72026-01-30 21:06:49 +0530371 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000373 if pDevEntry.PDevOmciCC != nil {
bseenivacfcd8f72026-01-30 21:06:49 +0530374 logger.Debugw(ctx, "pDevEntry.PDevOmciCC is not nil", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000376 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000377 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
378 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000380 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
381 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530382}
383
khenaidoo42dcdfd2021-10-19 17:34:12 -0400384func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000385 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000386
bseenivacfcd8f72026-01-30 21:06:49 +0530387 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000389 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
390 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000391 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530392 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 if dh.pOnuTP == nil {
394 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000395 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000396 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530397 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000398 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 if !dh.IsReadyForOmciConfig() {
401 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
402 "device-state": dh.GetDeviceReasonString()})
bseeniva0cbc62a2026-01-23 19:08:36 +0530403 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000406 //previous state test here was just this one, now extended for more states to reject the SetRequest:
407 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
408 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530409
Himani Chawla26e555c2020-08-31 12:30:20 +0530410 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
412 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000413 dh.pOnuTP.LockTpProcMutex()
414 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530415 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416
mpagenko44bd8362021-11-15 11:40:05 +0000417 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530418 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
419 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420 }
421 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000422 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800423 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000424 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
425 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800426 return err
427 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000428 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
429 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000430
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000431 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530432
Girish Gowdra50e56422021-06-01 16:46:04 -0700433 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400434 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000435 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
436 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000437
438 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
439 if err != nil {
440 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
441 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
442 // stopping all further processing
443 _ = dh.UpdateInterface(ctx)
444 return err
445 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 // if there has been some change for some uni TechProfilePath
447 //in order to allow concurrent calls to other dh instances we do not wait for execution here
448 //but doing so we can not indicate problems to the caller (who does what with that then?)
449 //by now we just assume straightforward successful execution
450 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
451 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530452
Girish Gowdra50e56422021-06-01 16:46:04 -0700453 // deadline context to ensure completion of background routines waited for
454 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
455 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
456 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000457
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700459
460 var wg sync.WaitGroup
461 wg.Add(1) // for the 1 go routine to finish
462 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700464 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
466 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 -0700467 return tpErr
468 }
469 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
470 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530471 defer cancel2()
472 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
473 if err1 != nil {
474 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
475 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700476 }
477 return nil
478 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000479 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700480 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700481 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000484 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
485 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 return nil
487}
488
khenaidoo42dcdfd2021-10-19 17:34:12 -0400489func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000490 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530491
bseeniva0cbc62a2026-01-23 19:08:36 +0530492 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 if dh.pOnuTP == nil {
494 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530497 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 dh.pOnuTP.LockTpProcMutex()
502 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530503 defer dh.lockDevice.RUnlock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530504
mpagenko0f543222021-11-03 16:24:14 +0000505 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
506 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
507 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530508 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
509 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510 }
511 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800513 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000514 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
515 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800516 return err
517 }
mpagenko0f543222021-11-03 16:24:14 +0000518 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
519 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000520 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000521
Mahir Gunyel9545be22021-07-04 15:53:16 -0700522 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524
Himani Chawla26e555c2020-08-31 12:30:20 +0530525}
526
khenaidoo42dcdfd2021-10-19 17:34:12 -0400527func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000528 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 +0000529
bseenivacfcd8f72026-01-30 21:06:49 +0530530 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000531 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
533 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530535 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530536 if dh.pOnuTP == nil {
537 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000538 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530540 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000541 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530542 }
543
Himani Chawla26e555c2020-08-31 12:30:20 +0530544 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000545 dh.pOnuTP.LockTpProcMutex()
546 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530547 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000548
mpagenko0f543222021-11-03 16:24:14 +0000549 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
550 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
551 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530552 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
553 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000554 }
555 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700556 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800558 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000559 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
560 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800561 return err
562 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530564
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000565 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
566 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530567 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000568 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 +0530569 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
570 if err1 != nil {
571 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
572 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000573 }
574
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000577
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000579
Mahir Gunyel9545be22021-07-04 15:53:16 -0700580func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
bseenivacfcd8f72026-01-30 21:06:49 +0530582 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700583 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
585 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530586 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700587 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700589 resourceName = "Gem"
590 } else {
591 resourceName = "Tcont"
592 }
593
594 // deadline context to ensure completion of background routines waited for
595 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
596 dctx, cancel := context.WithDeadline(context.Background(), deadline)
597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700599
600 var wg sync.WaitGroup
601 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700603 resource, entryID, &wg)
604 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
606 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700607 return err
608 }
609
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
611 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
612 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
613 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700614 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530615 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700616 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000617 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 +0530618 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
619 if err != nil {
620 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700621 return err
622 }
623 }
624 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700626 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530627 return nil
628}
629
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530630// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400632 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400633 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700634 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
635 var errorsList []error
636 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530637 if dh.GetPersRebootFlag(ctx) {
bseenivabc19dec2026-02-04 11:56:23 +0530638 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 +0530639 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
640 }
mpagenko01e726e2020-10-23 09:45:29 +0000641 //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 +0000642 if apOfFlowChanges.ToRemove != nil {
643 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000644 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000645 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 "device-id": dh.DeviceID})
647 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700648 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 }
651 flowInPort := flow.GetInPort(flowItem)
652 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
654 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700655 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000656 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000658 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000659 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000662 continue
663 } else {
664 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000666 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
667 loUniPort = uniPort
668 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000670 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000671 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000672 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700673 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000674 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000675 }
676 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
679 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700680
681 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
682 // Step1 : Fill flowControlBlock
683 // Step2 : Push the flowControlBlock to ONU channel
684 // Step3 : Wait on response channel for response
685 // Step4 : Return error value
686 startTime := time.Now()
687 respChan := make(chan error)
688 flowCb := FlowCb{
689 ctx: ctx,
690 addFlow: false,
691 flowItem: flowItem,
692 flowMetaData: nil,
693 uniPort: loUniPort,
694 respChan: &respChan,
695 }
696 dh.flowCbChan[loUniPort.UniID] <- flowCb
697 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
698 // Wait on the channel for flow handlers return value
699 retError = <-respChan
700 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
701 if retError != nil {
702 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
703 log.Fields{"device-id": dh.DeviceID, "error": retError})
704 errorsList = append(errorsList, retError)
705 continue
706 }
707 } else {
708 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
709 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000710 }
711 }
712 }
713 }
mpagenko01e726e2020-10-23 09:45:29 +0000714 if apOfFlowChanges.ToAdd != nil {
715 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
716 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000718 "device-id": dh.DeviceID})
719 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700720 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000721 continue
722 }
723 flowInPort := flow.GetInPort(flowItem)
724 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
726 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700727 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000728 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000730 } else if flowInPort == dh.ponPortNumber {
731 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000732 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000733 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000734 continue
735 } else {
736 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000738 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
739 loUniPort = uniPort
740 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000742 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000743 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700745 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000746 continue
mpagenko01e726e2020-10-23 09:45:29 +0000747 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000748 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
749 // if not, we just throw some error here to have an indication about that, if we really need to support that
750 // then we would need to create some means to activate the internal stored flows
751 // after the device gets active automatically (and still with its dependency to the TechProfile)
752 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
753 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000754 if !dh.IsReadyForOmciConfig() {
755 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
756 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700757 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
758 errorsList = append(errorsList, retError)
759 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000760 }
761
mpagenko01e726e2020-10-23 09:45:29 +0000762 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000764 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
765 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700766 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
767 // Step1 : Fill flowControlBlock
768 // Step2 : Push the flowControlBlock to ONU channel
769 // Step3 : Wait on response channel for response
770 // Step4 : Return error value
771 startTime := time.Now()
772 respChan := make(chan error)
773 flowCb := FlowCb{
774 ctx: ctx,
775 addFlow: true,
776 flowItem: flowItem,
777 flowMetaData: apFlowMetaData,
778 uniPort: loUniPort,
779 respChan: &respChan,
780 }
781 dh.flowCbChan[loUniPort.UniID] <- flowCb
782 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
783 // Wait on the channel for flow handlers return value
784 retError = <-respChan
785 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
786 if retError != nil {
787 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
788 log.Fields{"device-id": dh.DeviceID, "error": retError})
789 errorsList = append(errorsList, retError)
790 continue
791 }
792 } else {
793 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
794 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000795 }
796 }
797 }
798 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700799 if len(errorsList) > 0 {
800 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
801 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
802 }
803 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000804}
805
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530806// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
807// following are the expected device states after this activity:
808// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000809// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
811 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300812 dh.mutexForDisableDeviceRequested.Lock()
813 dh.disableDeviceRequested = true
814 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000815 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000816 //note that disableDevice sequences in some 'ONU active' state may yield also
817 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000818 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000820 //disable-device shall be just a UNi/ONU-G related admin state setting
821 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000822
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000824 // disable UNI ports/ONU
825 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
826 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000827 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000828 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000831 }
832 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000833 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000835 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400836 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000838 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400839 OperStatus: voltha.OperStatus_UNKNOWN,
840 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000841 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000842 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000843 }
mpagenko01e726e2020-10-23 09:45:29 +0000844 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000845
846 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000847 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000848 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300849 }
850}
851
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530852// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
854 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000855
mpagenkoaa3afe92021-05-21 16:20:58 +0000856 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000857 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
858 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
859 // for real ONU's that should have nearly no influence
860 // Note that for real ONU's there is anyway a problematic situation with following sequence:
861 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
862 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
863 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000864 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000865
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000866 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300868 dh.mutexForDisableDeviceRequested.Lock()
869 dh.disableDeviceRequested = false
870 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000871 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000872 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000873 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000876 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300877}
878
dbainbri4d3a0dc2020-12-02 00:33:42 +0000879func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530880 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000882 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 return
886 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000887 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000888 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000890 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000891 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000892 }
mpagenko101ac942021-11-16 15:01:29 +0000893 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000895 }
Himani Chawla4d908332020-08-31 12:30:20 +0530896 var onuIndication oop.OnuIndication
akashreddykb03dde02025-12-02 10:53:18 +0530897 var rebootInProgress bool
898 var persUniUnlockDone bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000899 pDevEntry.MutexPersOnuConfig.RLock()
900 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
901 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
902 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
903 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
akashreddykb03dde02025-12-02 10:53:18 +0530904 rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
905 persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 pDevEntry.MutexPersOnuConfig.RUnlock()
akashreddykb03dde02025-12-02 10:53:18 +0530907 if rebootInProgress {
908 if persUniUnlockDone {
909 logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
910 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
911 return
912 }
913 }
914 if onuIndication.OperState == "up" {
915 if err := dh.createInterface(ctx, &onuIndication); err != nil {
916 logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
917 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
918 return
919 }
920 } else {
921 logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
922 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
923 return
924 }
925 logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000926}
927
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000928func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530929 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000930
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000931 continueWithFlowConfig := false
932
bseenivacfcd8f72026-01-30 21:06:49 +0530933 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000934 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000935 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000936 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
937 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000938 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530939 dh.lockDevice.RLock()
940 if dh.pOnuTP == nil {
941 //should normally not happen ...
942 logger.Warnw(ctx, "onuTechProf instance not set up for reconcile tech prof - ignoring request",
943 log.Fields{"device-id": dh.DeviceID})
944 dh.lockDevice.RUnlock()
945 return continueWithFlowConfig
946 }
947
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000948 dh.pOnuTP.LockTpProcMutex()
949 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530950 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000951
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000953 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
955 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530956 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000958 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
959 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000960 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000961 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700962 techProfsFound := false
963 techProfInstLoadFailed := false
964outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000966 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000967 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000968 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000970 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000972 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
974 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000975 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000977 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700978 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000979 var iaTechTpInst ia.TechProfileDownloadMessage
980 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800981 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000982 pDevEntry.MutexReconciledTpInstances.RLock()
983 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
984 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000985 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000986 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700987 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000988 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 break outerLoop
990 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000991 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000992 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700993 var tpInst tech_profile.TechProfileInstance
994 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400995 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700996 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000997 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700999 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001000 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001001 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001002 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1003 break outerLoop
1004 }
1005
Girish Gowdra041dcb32020-11-16 16:54:30 -08001006 // deadline context to ensure completion of background routines waited for
1007 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
1008 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001009 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001010
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001011 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001012 var wg sync.WaitGroup
1013 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001015 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001016 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
1017 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001018 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1019 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -08001020 }
mpagenko2dc896e2021-08-02 12:03:59 +00001021 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001022 if len(uniData.PersFlowParams) != 0 {
1023 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001024 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +00001026 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001027 } // for all UNI entries from SOnuPersistentData
1028 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
1029 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001030 }
mpagenko2dc896e2021-08-02 12:03:59 +00001031
1032 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1033 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001034
1035 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +00001036}
1037
1038func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1039 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1040 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301041 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001043 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001044 return
1045 }
mpagenko2dc896e2021-08-02 12:03:59 +00001046 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001047 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001048 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001049 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001050 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001051 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001052 }
mpagenko2dc896e2021-08-02 12:03:59 +00001053 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301054 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001056 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001057 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058}
1059
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001060func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1061 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062
bseenivacfcd8f72026-01-30 21:06:49 +05301063 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001065 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001066 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001067 return
1068 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001069
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 pDevEntry.MutexPersOnuConfig.RLock()
1071 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1072 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301073 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001075 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001076 return
1077 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001078 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001079 var uniVlanConfigEntries []uint8
1080 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1081
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001083 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1084 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001085 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001086 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001087 continue
1088 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001089 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001090 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001091 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001092 // It doesn't make sense to configure any flows if no TPs are available
1093 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1096 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001097 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001098 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001099
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001100 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001101 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001102 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1105 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001106 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001107 return
1108 }
mpagenko101ac942021-11-16 15:01:29 +00001109 //needed to split up function due to sca complexity
1110 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1111
mpagenko2dc896e2021-08-02 12:03:59 +00001112 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001113 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001114 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1115 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001116 // this can't be used as global finished reconciling flag because
1117 // assumes is getting called before the state machines for the last flow is completed,
1118 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001119 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1120 } // for all UNI entries from SOnuPersistentData
1121 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001122
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001123 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301124 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001125 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001126 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001127 return
1128 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001129 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1130 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1131 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1132 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1133 log.Fields{"device-id": dh.DeviceID})
1134 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1135 if pDevEntry != nil {
1136 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001137 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001138 } else {
1139 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1140 log.Fields{"device-id": dh.DeviceID})
1141 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1142 if pDevEntry != nil {
1143 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1144 }
1145 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001146 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001147 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001148}
1149
mpagenko101ac942021-11-16 15:01:29 +00001150func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1151 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1152 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1153 flowsProcessed := 0
1154 lastFlowToReconcile := false
1155 loUniID := apUniPort.UniID
1156 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001157 if !(*apFlowsFound) {
1158 *apFlowsFound = true
1159 syncChannel := make(chan struct{})
1160 // start go routine with select() on reconciling vlan config channel before
1161 // starting vlan config reconciling process to prevent loss of any signal
1162 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1163 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1164 //block until the wait routine is really blocked on channel input
1165 // in order to prevent to early ready signal from VlanConfig processing
1166 <-syncChannel
1167 }
1168 if flowsProcessed == len(aPersFlowParam)-1 {
1169 var uniAdded bool
1170 lastFlowToReconcile = true
1171 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1172 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001173 }
1174 }
mpagenko101ac942021-11-16 15:01:29 +00001175 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1176 "device-id": dh.DeviceID, "uni-id": loUniID,
1177 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1178 dh.lockVlanConfig.Lock()
1179 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1180 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1181 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301182 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 +00001183 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1184 }
1185 } else {
1186 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301187 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301188 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001189 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1190 }
1191 }
1192 dh.lockVlanConfig.Unlock()
1193 flowsProcessed++
1194 } //for all flows of this UNI
1195}
1196
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301197// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1198//
1199// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001200func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1201 waitGroup *cmn.WaitGroupWithTimeOut) {
1202 var reconciledUniVlanConfigEntries []uint8
1203 var appended bool
1204 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1205 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1206 "device-id": dh.DeviceID, "expiry": expiry})
1207 // indicate blocking on channel now to the caller
1208 aSyncChannel <- struct{}{}
1209 for {
1210 select {
1211 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1212 switch uniIndication {
1213 // no activity requested (should normally not be received) - just continue waiting
1214 case cWaitReconcileFlowNoActivity:
1215 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1216 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301217 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001218 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1219 return
1220 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1221 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301222 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001223 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1224 return
1225 // this should be a valid UNI vlan config done indication
1226 default:
1227 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301228 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001229 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1230 if reconciledUniVlanConfigEntries, appended =
1231 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1232 waitGroup.Done()
1233 }
1234 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301235 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 +00001236 }
1237 } //switch uniIndication
1238
1239 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1240 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1241 log.Fields{"device-id": dh.DeviceID})
1242 return
1243 }
1244 }
1245}
1246
1247func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1248 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1249}
1250
1251func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1252 for _, ele := range slice {
1253 if ele == val {
1254 return slice, false
1255 }
1256 }
1257 return append(slice, val), true
1258}
1259
1260// sendChReconcileFinished - sends true or false on reconcileFinish channel
1261func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1262 if dh != nil { //if the object still exists (might have been already deleted in background)
1263 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1264 select {
1265 case dh.chReconcilingFinished <- success:
1266 default:
1267 }
1268 }
1269}
1270
1271// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1272func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1273 if dh != nil { //if the object still exists (might have been already deleted in background)
1274 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1275 select {
1276 case dh.chUniVlanConfigReconcilingDone <- value:
1277 default:
1278 }
1279 }
1280}
1281
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301282func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1283 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1284
1285 defer dh.UpdateAndStoreRebootState(ctx, false)
1286 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1287 if pDevEntry == nil {
1288 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1289 return
1290 }
1291
1292 pDevEntry.MutexPersOnuConfig.RLock()
1293 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1294 pDevEntry.MutexPersOnuConfig.RUnlock()
1295 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1296 log.Fields{"device-id": dh.DeviceID})
1297 return
1298 }
1299 flowsFound := false
1300 var uniVlanConfigEntries []uint8
1301 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1302
1303 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1304 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1305 if len(uniData.PersFlowParams) == 0 {
1306 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1307 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1308 continue
1309 }
1310 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1311 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1312 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1313 // It doesn't make sense to configure any flows if no TPs are available
1314 continue
1315 }
1316 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1317 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1318 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1319 pDevEntry.MutexPersOnuConfig.RUnlock()
1320
1321 var uniPort *cmn.OnuUniPort
1322 var exist bool
1323 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1324 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1325 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1326 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1327 return
1328 }
1329
1330 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1331
1332 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1333 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1334 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1335 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1336 // this can't be used as global finished reconciling flag because
1337 // assumes is getting called before the state machines for the last flow is completed,
1338 // while this is not guaranteed.
1339 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1340 } // for all UNI entries from SOnuPersistentData
1341 pDevEntry.MutexPersOnuConfig.RUnlock()
1342
1343 if !flowsFound {
1344 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1345 log.Fields{"device-id": dh.DeviceID})
1346 return
1347 }
1348 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1349 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1350 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1351 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1352 log.Fields{"device-id": dh.DeviceID})
1353 } else {
1354 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1355 log.Fields{"device-id": dh.DeviceID})
1356 return
1357 }
1358}
1359
1360func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1361 dh.UpdateRebootPersData(ctx, flag)
1362 if err := dh.StorePersistentData(ctx); err != nil {
1363 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1364 }
1365}
1366
1367func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1368 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1369 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1370 flowsProcessed := 0
1371 lastFlowToConfigOnReboot := false
1372 loUniID := apUniPort.UniID
1373 for _, flowData := range aPersFlowParam {
1374 if !(*apFlowsFound) {
1375 *apFlowsFound = true
1376 syncChannel := make(chan struct{})
1377 // start go routine with select() on reconciling vlan config channel before
1378 // starting vlan config reconciling process to prevent loss of any signal
1379 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1380 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1381 //block until the wait routine is really blocked on channel input
1382 // in order to prevent to early ready signal from VlanConfig processing
1383 <-syncChannel
1384 }
1385 if flowsProcessed == len(aPersFlowParam)-1 {
1386 var uniAdded bool
1387 lastFlowToConfigOnReboot = true
1388 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1389 apWaitGroup.Add(1) //increment the waiting group
1390 }
1391 }
1392 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1393 "device-id": dh.DeviceID, "uni-id": loUniID,
1394 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1395 dh.lockVlanConfig.Lock()
1396 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1397 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1398 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1399 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 {
1400 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1401 }
1402 } else {
1403 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1404 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1405 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1406 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1407 }
1408 }
1409 dh.lockVlanConfig.Unlock()
1410 flowsProcessed++
1411 } //for all flows of this UNI
1412}
1413
1414func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1415 waitGroup *cmn.WaitGroupWithTimeOut) {
1416 var rebootUniVlanConfigEntries []uint8
1417 var appended bool
1418 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1419 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1420 "device-id": dh.DeviceID, "expiry": expiry})
1421 // indicate blocking on channel now to the caller
1422 aSyncChannel <- struct{}{}
1423 for {
1424 select {
1425 case <-dh.deviceDeleteCommChan:
1426 // Cancel the context and return
1427 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1428 return
1429
1430 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1431 switch uniIndication {
1432 // this should be a valid UNI vlan config done indication
1433 default:
1434 if uniIndication < platform.MaxUnisPerOnu {
1435 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1436 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1437 if rebootUniVlanConfigEntries, appended =
1438 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1439 waitGroup.Done()
1440 }
1441 } else {
1442 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1443 }
1444 } //switch uniIndication
1445
1446 case <-time.After(expiry):
1447 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1448 log.Fields{"device-id": dh.DeviceID})
1449 return
1450 }
1451 }
1452}
1453
1454func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1455 if dh != nil { //if the object still exists (might have been already deleted in background)
1456 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1457 select {
1458 case dh.chUniVlanConfigOnRebootDone <- value:
1459 default:
1460 }
1461 }
1462}
1463
1464func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
bseenivabc19dec2026-02-04 11:56:23 +05301465 logger.Infow(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301466 techProfInstLoadFailed := false
1467 continueWithFlowConfig := false
1468 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1469 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1470 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1471
1472 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1473 if pDevEntry == nil {
1474 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1475 return continueWithFlowConfig
1476 }
1477 dh.lockDevice.RLock()
1478 if dh.pOnuTP == nil {
1479 //should normally not happen ...
1480 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1481 log.Fields{"device-id": dh.DeviceID})
1482 dh.lockDevice.RUnlock()
1483 return continueWithFlowConfig
1484 }
1485
1486 dh.pOnuTP.LockTpProcMutex()
1487 defer dh.pOnuTP.UnlockTpProcMutex()
1488 defer dh.lockDevice.RUnlock()
1489
1490 pDevEntry.MutexPersOnuConfig.RLock()
1491 persMutexLock := true
1492 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1493 pDevEntry.MutexPersOnuConfig.RUnlock()
1494 logger.Info(ctx, "no uni-configs have been stored - aborting",
1495 log.Fields{"device-id": dh.DeviceID})
1496 return continueWithFlowConfig
1497 }
1498
1499outerLoop:
1500 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1501 uniID := uniData.PersUniID
1502
1503 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1504 logger.Debugw(ctx, "no TPs stored for uniID",
1505 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1506 continue
1507 }
1508 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1509 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1510 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1511 pDevEntry.MutexPersOnuConfig.RUnlock()
1512 persMutexLock = false
1513 for tpID, tpPath := range uniData.PersTpPathMap {
1514 if tpPath != "" {
1515 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1516 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1517 })
1518 // Attempt the initial call before entering the retry loop
1519 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1520 if err != nil {
1521 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1522 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1523 })
1524 techProfInstLoadFailed = true
1525 break outerLoop
1526 }
1527 if iaTechTpInst != nil {
1528 var tpInst tech_profile.TechProfileInstance
1529 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1530 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1531 tpInst = *techTpInst.TpInstance
1532 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1533 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1534 default: // do not support epon or other tech
1535 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1536 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1537 techProfInstLoadFailed = true
1538 break outerLoop
1539 }
1540
1541 continueWithFlowConfig = true
1542 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1543 dctx, cancel := context.WithDeadline(ctx, deadline)
1544
1545 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1546 var wg sync.WaitGroup
1547 wg.Add(1) // for the 1 go routine to finish
1548 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1549 // Wait for either completion or cancellation
1550 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1551 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1552 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1553 techProfInstLoadFailed = true
1554 continueWithFlowConfig = false
1555 break outerLoop
1556 }
1557 } else {
1558 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1559 techProfInstLoadFailed = true
1560 break outerLoop
1561 }
1562 } else {
1563 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1564 "uni-id": uniID, "device-id": dh.DeviceID})
1565 techProfInstLoadFailed = true
1566 break outerLoop
1567 }
1568 }
1569 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1570 persMutexLock = true
1571 }
1572 if persMutexLock {
1573 pDevEntry.MutexPersOnuConfig.RUnlock()
1574 }
1575 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1576 return continueWithFlowConfig
1577}
1578
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001580 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001581
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001583 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001584 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001585 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001586 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001587 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001588
1589 // deadline context to ensure completion of background routines waited for
1590 //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 +05301591 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301593 defer cancel()
1594 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1595 if err != nil {
1596 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1597 return err
1598 }
1599 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001600}
1601
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301602// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001603// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301604//
1605// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1606//
1607// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301608func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001610 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301612 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001613 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301615 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001616 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301617 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301618 }
mpagenko01e726e2020-10-23 09:45:29 +00001619
1620 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001622
mpagenko44bd8362021-11-15 11:40:05 +00001623 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001625 // 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 +05301626 go func() {
1627 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1628 DeviceId: dh.DeviceID,
1629 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1630 OperStatus: voltha.OperStatus_DISCOVERED,
1631 }); err != nil {
1632 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1633 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1634 return
1635 }
bseenivabc19dec2026-02-04 11:56:23 +05301636 if dh.GetDeviceTechProfOnReboot() {
1637 dh.UpdateAndStoreRebootState(ctx, true)
1638 }
akashreddyke30dfa92025-11-26 10:51:57 +05301639 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1640 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1641 return
1642 }
1643 dh.SetReadyForOmciConfig(false)
1644 }()
1645 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001646 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1647 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1648 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1649 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001650}
1651
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301652// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1653//
1654// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001655func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001657 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001658 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001659
1660 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301661 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001662 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1664 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001665 }
1666
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001668 var inactiveImageID uint16
1669 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1670 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001671 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1672 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001673 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001675 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001676 if err == nil {
1677 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1678 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001679 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001680 }
1681 } else {
1682 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001684 }
mpagenko15ff4a52021-03-02 10:09:20 +00001685 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001686 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001688 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1689 dh.upgradeCanceled = true
1690 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1691 }
mpagenko38662d02021-08-11 09:45:19 +00001692 //no effort spent anymore for the old API to automatically cancel and restart the download
1693 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001694 }
mpagenko15ff4a52021-03-02 10:09:20 +00001695 } else {
1696 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001698 }
1699 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001700 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1701 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001702 }
1703 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001704}
1705
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301706// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001707// after the OnuImage has been downloaded to the adapter, called in background
1708func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
bseeniva0b4286b2026-01-30 13:05:42 +05301709 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string, aCancel context.CancelFunc) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001710
1711 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301712 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001713 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001714 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001715 return
1716 }
1717
1718 var inactiveImageID uint16
1719 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1720 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001721 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001722
mpagenko59862f02021-10-11 08:53:18 +00001723 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001724 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001725 // but must be still locked at calling createOnuUpgradeFsm
1726 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1727 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1728 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001729 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1730 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001731 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001732 //flush the remove upgradeFsmChan channel
1733 select {
1734 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001735 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001736 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001737 }
mpagenko59862f02021-10-11 08:53:18 +00001738 dh.lockUpgradeFsm.Unlock()
1739 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1740 dh.upgradeCanceled = true
1741 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1742 }
mpagenko38662d02021-08-11 09:45:19 +00001743 select {
1744 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001746 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1747 return
1748 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001749 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001750 }
mpagenko59862f02021-10-11 08:53:18 +00001751 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001752 }
mpagenko38662d02021-08-11 09:45:19 +00001753
1754 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001755 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001756 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001757 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001758 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001759 if err == nil {
1760 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1761 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1762 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001763 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001764 return
1765 }
mpagenko38662d02021-08-11 09:45:19 +00001766 } else {
1767 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001768 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001769 }
bseeniva0b4286b2026-01-30 13:05:42 +05301770 go func() {
1771 onuDlChn := dh.pOnuUpradeFsm.GetOnuDLChannel()
1772 select {
1773 case <-ctx.Done():
1774 logger.Errorw(ctx, "context Deadline Exceeded aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1775 dh.lockUpgradeFsm.Lock()
1776 if dh.pOnuUpradeFsm != nil {
1777 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1778 }
1779 dh.lockUpgradeFsm.Unlock()
1780 return
1781 case <-dh.deviceDeleteCommChan:
1782 logger.Errorw(ctx, "device deleted aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1783 dh.lockUpgradeFsm.Lock()
1784 if dh.pOnuUpradeFsm != nil {
1785 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1786 }
1787 dh.lockUpgradeFsm.Unlock()
1788 return
1789 case success := <-onuDlChn:
1790 logger.Infow(ctx, "onu SW upgrade download completed", log.Fields{"isSuccess": success, "device-id": dh.DeviceID})
1791 aCancel()
1792 return
1793
1794 }
1795 }()
mpagenkoc26d4c02021-05-06 14:27:57 +00001796 return
1797 }
1798 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001799 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001800}
1801
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301802// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001803func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1804 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001805 var err error
1806 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1807 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1808 // 2.) activation of the inactive image
1809
bseenivacfcd8f72026-01-30 21:06:49 +05301810 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001811 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001812 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1813 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001814 }
1815 dh.lockUpgradeFsm.RLock()
1816 if dh.pOnuUpradeFsm != nil {
1817 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001818 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001819 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001820 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1821 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001822 }
mpagenko59862f02021-10-11 08:53:18 +00001823 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1824 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1825 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1826 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001827 // use the OnuVendor identification from this device for the internal unique name
1828 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001829 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001830 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001831 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001832 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001833 "device-id": dh.DeviceID, "error": err})
1834 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001835 }
mpagenko183647c2021-06-08 15:25:04 +00001836 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001838 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001839 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001840 } //else
1841 dh.lockUpgradeFsm.RUnlock()
1842
1843 // 2.) check if requested image-version equals the inactive one and start its activation
1844 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1845 var inactiveImageID uint16
1846 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1847 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001848 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1849 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001850 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001851 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001853 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001854 if err == nil {
1855 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1856 inactiveImageID, aCommitRequest); err != nil {
1857 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001858 "device-id": dh.DeviceID, "error": err})
1859 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001860 }
1861 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001862 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001863 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001864 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001865 } //else
1866 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001867 "device-id": dh.DeviceID, "error": err})
1868 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001869}
1870
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301871// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001872func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1873 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001874 var err error
1875 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1876 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1877 // 2.) commitment of the active image
1878
bseenivacfcd8f72026-01-30 21:06:49 +05301879 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001880 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001881 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1882 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001883 }
1884 dh.lockUpgradeFsm.RLock()
1885 if dh.pOnuUpradeFsm != nil {
1886 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001887 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001888 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001889 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1890 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001891 }
mpagenko59862f02021-10-11 08:53:18 +00001892 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1893 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1894 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1895 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001896 // use the OnuVendor identification from this device for the internal unique name
1897 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001898 // 1.) check a started upgrade process and relay the commitment request to it
1899 // the running upgrade may be based either on the imageIdentifier (started from download)
1900 // or on the imageVersion (started from pure activation)
1901 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1902 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001903 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001904 "device-id": dh.DeviceID, "error": err})
1905 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001906 }
mpagenko183647c2021-06-08 15:25:04 +00001907 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001909 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001910 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001911 } //else
1912 dh.lockUpgradeFsm.RUnlock()
1913
mpagenko183647c2021-06-08 15:25:04 +00001914 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001915 var activeImageID uint16
1916 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1917 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1919 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001920 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001921 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001923 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001924 if err == nil {
1925 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1926 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 "device-id": dh.DeviceID, "error": err})
1928 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001929 }
1930 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001931 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001932 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001933 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001934 } //else
1935 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 "device-id": dh.DeviceID, "error": err})
1937 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001938}
1939
mpagenkoaa3afe92021-05-21 16:20:58 +00001940func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001941 aVersion string) *voltha.ImageState {
1942 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001943 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001944 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001945 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001946 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1947 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1948 if aVersion == dh.pLastUpgradeImageState.Version {
1949 pImageState = dh.pLastUpgradeImageState
1950 } else { //state request for an image version different from last processed image version
1951 pImageState = &voltha.ImageState{
1952 Version: aVersion,
1953 //we cannot state something concerning this version
1954 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1955 Reason: voltha.ImageState_NO_ERROR,
1956 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1957 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001958 }
1959 }
mpagenko38662d02021-08-11 09:45:19 +00001960 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001961}
1962
1963func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1964 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001966 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001967 dh.lockUpgradeFsm.RLock()
1968 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001969 dh.lockUpgradeFsm.RUnlock()
1970 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001971 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001972 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1973 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1974 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1975 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1976 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1977 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001978 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1979 dh.upgradeCanceled = true
1980 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1981 }
mpagenko45586762021-10-01 08:30:22 +00001982 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001983 } else {
mpagenko45586762021-10-01 08:30:22 +00001984 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001985 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1986 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1987 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1988 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1989 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1990 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001991 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1992 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001993 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1994 //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 +00001995 }
1996}
1997
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001998func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1999
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002000 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002001
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002002 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002003 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
2005 pDevEntry.MutexOnuImageStatus.Lock()
2006 pDevEntry.POnuImageStatus = onuImageStatus
2007 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002008
2009 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002011 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
2012 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002013 images, err := onuImageStatus.GetOnuImageStatus(ctx)
2014 pDevEntry.MutexOnuImageStatus.Lock()
2015 pDevEntry.POnuImageStatus = nil
2016 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002017 return images, err
2018}
2019
Himani Chawla6d2ae152020-09-02 13:11:20 +05302020// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002021// #####################################################################################
2022
2023// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302024// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002025
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002027 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
2028 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002029}
2030
2031// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002034 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002035 var err error
2036
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002037 // populate what we know. rest comes later after mib sync
2038 dh.device.Root = false
2039 dh.device.Vendor = "OpenONU"
2040 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002041 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00002042 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002043
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002044 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002046 if !dh.IsReconciling() {
2047 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302048 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002049 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2050 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302051 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002052 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302053 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002054 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002055 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002056
Himani Chawla4d908332020-08-31 12:30:20 +05302057 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002058 dh.ponPortNumber = dh.device.ParentPortNo
2059
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002060 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2061 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2062 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002063 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002064 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302065 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002066
2067 /*
2068 self._pon = PonPort.create(self, self._pon_port_number)
2069 self._pon.add_peer(self.parent_id, self._pon_port_number)
2070 self.logger.debug('adding-pon-port-to-agent',
2071 type=self._pon.get_port().type,
2072 admin_state=self._pon.get_port().admin_state,
2073 oper_status=self._pon.get_port().oper_status,
2074 )
2075 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002076 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302077 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002078 var ponPortNo uint32 = 1
2079 if dh.ponPortNumber != 0 {
2080 ponPortNo = dh.ponPortNumber
2081 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002082
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002083 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002084 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002085 PortNo: ponPortNo,
2086 Label: fmt.Sprintf("pon-%d", ponPortNo),
2087 Type: voltha.Port_PON_ONU,
2088 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302089 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002090 PortNo: ponPortNo}}, // Peer port is parent's port number
2091 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002092 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002093 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002094 e.Cancel(err)
2095 return
2096 }
2097 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302098 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002099 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002100 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002101}
2102
2103// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002105
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002106 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002107 var err error
2108 /*
2109 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2110 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2111 return nil
2112 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002114 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002115 e.Cancel(err)
2116 return
2117 }
2118
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002121 // reconcilement will be continued after mib download is done
2122 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002123
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002124 /*
2125 ############################################################################
2126 # Setup Alarm handler
2127 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2128 device.serial_number)
2129 ############################################################################
2130 # Setup PM configuration for this device
2131 # Pass in ONU specific options
2132 kwargs = {
2133 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2134 'heartbeat': self.heartbeat,
2135 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2136 }
2137 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2138 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2139 self.logical_device_id, device.serial_number,
2140 grouped=True, freq_override=False, **kwargs)
2141 pm_config = self._pm_metrics.make_proto()
2142 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2143 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2144 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2145
2146 # Note, ONU ID and UNI intf set in add_uni_port method
2147 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2148 ani_ports=[self._pon])
2149
2150 # Code to Run OMCI Test Action
2151 kwargs_omci_test_action = {
2152 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2153 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2154 }
2155 serial_number = device.serial_number
2156 self._test_request = OmciTestRequest(self.core_proxy,
2157 self.omci_agent, self.device_id,
2158 AniG, serial_number,
2159 self.logical_device_id,
2160 exclusive=False,
2161 **kwargs_omci_test_action)
2162
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002164 else:
2165 self.logger.info('onu-already-activated')
2166 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002167
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002168 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002169}
2170
2171// doStateConnected get the device info and update to voltha core
2172// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302173//
2174// voltha-openolt-adapter/adaptercore/device_handler.go
2175// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002177
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002178 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302179 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002180 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002181 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002182}
2183
2184// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002186
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002187 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302188 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002189 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002190 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002191
2192 /*
2193 // Synchronous call to update device state - this method is run in its own go routine
2194 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2195 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002196 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 +00002197 return err
2198 }
2199 return nil
2200 */
2201}
2202
2203// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002205
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002206 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002207 var err error
2208
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002209 device := dh.device
2210 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002211 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002213 e.Cancel(err)
2214 return
2215 }
2216
2217 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002219 /*
2220 // Update the all ports state on that device to disable
2221 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002222 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002223 return er
2224 }
2225
2226 //Update the device oper state and connection status
2227 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2228 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2229 dh.device = cloned
2230
2231 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002232 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002233 return er
2234 }
2235
2236 //get the child device for the parent device
2237 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2238 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002239 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002240 return err
2241 }
2242 for _, onuDevice := range onuDevices.Items {
2243
2244 // Update onu state as down in onu adapter
2245 onuInd := oop.OnuIndication{}
2246 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002247 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002248 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2249 if er != nil {
2250 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002251 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002252 //Do not return here and continue to process other ONUs
2253 }
2254 }
2255 // * Discovered ONUs entries need to be cleared , since after OLT
2256 // is up, it starts sending discovery indications again* /
2257 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002258 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002259 return nil
2260 */
Himani Chawla4d908332020-08-31 12:30:20 +05302261 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002262 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002263 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002264}
2265
Himani Chawla6d2ae152020-09-02 13:11:20 +05302266// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002267// #################################################################################
2268
2269// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302270// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002271
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302272// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002274 dh.lockDevice.RLock()
2275 pOnuDeviceEntry := dh.pOnuOmciDevice
2276 if aWait && pOnuDeviceEntry == nil {
2277 //keep the read sema short to allow for subsequent write
2278 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002279 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002280 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2281 // so it might be needed to wait here for that event with some timeout
2282 select {
2283 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002285 return nil
2286 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002287 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002288 // if written now, we can return the written value without sema
2289 return dh.pOnuOmciDevice
2290 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002291 }
mpagenko3af1f032020-06-10 08:53:41 +00002292 dh.lockDevice.RUnlock()
2293 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002294}
2295
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302296// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2298 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002299 dh.lockDevice.Lock()
2300 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002301 dh.pOnuOmciDevice = apDeviceEntry
2302 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002303 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302304 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002305 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002306}
2307
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302308// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302309//
2310//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302311func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002312 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002313
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002315 if deviceEntry == nil {
2316 /* costum_me_map in python code seems always to be None,
2317 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2318 /* also no 'clock' argument - usage open ...*/
2319 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2321 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2322 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2323 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2324 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002325 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002327 // fire deviceEntry ready event to spread to possibly waiting processing
2328 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002330 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002331 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002332 }
2333 // might be updated with some error handling !!!
2334 return nil
2335}
2336
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002338 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002339 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2340
2341 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002342
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002344 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2346 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002347 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302348
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002352
khenaidoo42dcdfd2021-10-19 17:34:12 -04002353 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002355 OperStatus: voltha.OperStatus_ACTIVATING,
2356 ConnStatus: voltha.ConnectStatus_REACHABLE,
2357 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002358 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302360 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2361 }
2362 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2363 if dh.GetDeviceTechProfOnReboot() {
2364 pDevEntry.MutexPersOnuConfig.Lock()
2365 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2366 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302367 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302368 pDevEntry.MutexPersOnuConfig.Unlock()
2369 }
2370 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2371 if err := dh.StorePersistentData(ctx); err != nil {
2372 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2373 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002374 }
2375 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302376 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002377 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002378
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 pDevEntry.MutexPersOnuConfig.RLock()
2380 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2381 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382 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 +00002383 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002384 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302385
2386 //VOL-4965: Recover previously Activating ONU during reconciliation.
2387 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2388 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2389 log.Fields{"device-id": dh.DeviceID})
2390 pDevEntry.MutexPersOnuConfig.Lock()
2391 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2392 pDevEntry.MutexPersOnuConfig.Unlock()
2393 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002394 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002395 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002396 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002397 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002398 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2399 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2400 // 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 +00002401 // 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 +00002402 // so let's just try to keep it simple ...
2403 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002404 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002405 if err != nil || device == nil {
2406 //TODO: needs to handle error scenarios
2407 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2408 return errors.New("Voltha Device not found")
2409 }
2410 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002411
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002413 return err
mpagenko3af1f032020-06-10 08:53:41 +00002414 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002415 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302416 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2417 /* this might be a good time for Omci Verify message? */
2418 verifyExec := make(chan bool)
2419 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2420 dh.device.Id, pDevEntry.PDevOmciCC, false,
2421 true, true) //exclusive and allowFailure (anyway not yet checked)
2422 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002423
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302424 /* give the handler some time here to wait for the OMCi verification result
2425 after Timeout start and try MibUpload FSM anyway
2426 (to prevent stopping on just not supported OMCI verification from ONU) */
2427 select {
2428 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2429 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2430 case testresult := <-verifyExec:
2431 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2432 case <-dh.deviceDeleteCommChan:
2433 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2434 return nil
2435 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002436 }
2437
2438 /* In py code it looks earlier (on activate ..)
2439 # Code to Run OMCI Test Action
2440 kwargs_omci_test_action = {
2441 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2442 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2443 }
2444 serial_number = device.serial_number
2445 self._test_request = OmciTestRequest(self.core_proxy,
2446 self.omci_agent, self.device_id,
2447 AniG, serial_number,
2448 self.logical_device_id,
2449 exclusive=False,
2450 **kwargs_omci_test_action)
2451 ...
2452 # Start test requests after a brief pause
2453 if not self._test_request_started:
2454 self._test_request_started = True
2455 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2456 reactor.callLater(tststart, self._test_request.start_collector)
2457
2458 */
2459 /* which is then: in omci_test_request.py : */
2460 /*
2461 def start_collector(self, callback=None):
2462 """
2463 Start the collection loop for an adapter if the frequency > 0
2464
2465 :param callback: (callable) Function to call to collect PM data
2466 """
2467 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2468 if callback is None:
2469 callback = self.perform_test_omci
2470
2471 if self.lc is None:
2472 self.lc = LoopingCall(callback)
2473
2474 if self.default_freq > 0:
2475 self.lc.start(interval=self.default_freq / 10)
2476
2477 def perform_test_omci(self):
2478 """
2479 Perform the initial test request
2480 """
2481 ani_g_entities = self._device.configuration.ani_g_entities
2482 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2483 is not None else None
2484 self._entity_id = ani_g_entities_ids[0]
2485 self.logger.info('perform-test', entity_class=self._entity_class,
2486 entity_id=self._entity_id)
2487 try:
2488 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2489 result = yield self._device.omci_cc.send(frame)
2490 if not result.fields['omci_message'].fields['success_code']:
2491 self.logger.info('Self-Test Submitted Successfully',
2492 code=result.fields[
2493 'omci_message'].fields['success_code'])
2494 else:
2495 raise TestFailure('Test Failure: {}'.format(
2496 result.fields['omci_message'].fields['success_code']))
2497 except TimeoutError as e:
2498 self.deferred.errback(failure.Failure(e))
2499
2500 except Exception as e:
2501 self.logger.exception('perform-test-Error', e=e,
2502 class_id=self._entity_class,
2503 entity_id=self._entity_id)
2504 self.deferred.errback(failure.Failure(e))
2505
2506 */
2507
2508 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002510
mpagenko1cc3cb42020-07-27 15:24:38 +00002511 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2512 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2513 * 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 +05302514 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002515 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302516
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302518 // Breaking this part of code due to sca complexity
2519 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2520 return err
2521}
2522
2523func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002525 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002526 if pMibUlFsm.Is(mib.UlStDisabled) {
2527 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2528 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2529 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302530 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002531 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302532 //Determine ONU status and start/re-start MIB Synchronization tasks
2533 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534 if pDevEntry.IsNewOnu() {
2535 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2536 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2537 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002538 }
Himani Chawla4d908332020-08-31 12:30:20 +05302539 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002540 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2541 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2542 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302543 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002544 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002545 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002546 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002547 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 "device-id": dh.DeviceID})
2549 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002550 }
2551 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2553 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002554 }
2555 return nil
2556}
2557
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002558func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002559 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002560 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302562 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002563
mpagenko900ee4b2020-10-12 11:56:34 +00002564 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2565 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2566 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002567 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002570 // abort: system behavior is just unstable ...
2571 return err
2572 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002573 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302574 if !dh.GetDeviceTechProfOnReboot() {
2575 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2576 }
mpagenko900ee4b2020-10-12 11:56:34 +00002577
2578 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002579 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002581 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2583 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002584 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002586
2587 //TODO!!! remove existing traffic profiles
2588 /* from py code, if TP's exist, remove them - not yet implemented
2589 self._tp = dict()
2590 # Let TP download happen again
2591 for uni_id in self._tp_service_specific_task:
2592 self._tp_service_specific_task[uni_id].clear()
2593 for uni_id in self._tech_profile_download_done:
2594 self._tech_profile_download_done[uni_id].clear()
2595 */
2596
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002600
mpagenkoe4782082021-11-25 12:04:26 +00002601 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002602 // abort: system behavior is just unstable ...
2603 return err
2604 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002607 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002608 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002609 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2610 OperStatus: voltha.OperStatus_DISCOVERED,
2611 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002612 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002615 // abort: system behavior is just unstable ...
2616 return err
2617 }
akashreddykb03dde02025-12-02 10:53:18 +05302618 if dh.GetDeviceTechProfOnReboot() {
2619 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2620 if err := dh.StorePersistentData(ctx); err != nil {
2621 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2622 log.Fields{"device-id": dh.DeviceID, "err": err})
2623 }
2624 }
mpagenko3af1f032020-06-10 08:53:41 +00002625 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002626 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002627 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002628 return nil
2629}
2630
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002631func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002632 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2633 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2634 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2635 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002636 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002637
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002638 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302639 //VOL-5260: During race conditions when adoptDevice has not yet completed
2640 // and deleteDevice is issued , returning error will further prevent clean up
2641 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002642 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302643 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2644 logger.Error(ctx, errMsg)
2645 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002646 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002647 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002648 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002649 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 pDevEntry.MutexOnuImageStatus.RLock()
2651 if pDevEntry.POnuImageStatus != nil {
2652 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002653 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002654 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002655
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002656 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002657 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002658 }
2659 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002660 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002661 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002663 }
mpagenko101ac942021-11-16 15:01:29 +00002664 //stop any deviceHandler reconcile processing (if running)
2665 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002666 //port lock/unlock FSM's may be active
2667 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002669 }
2670 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002671 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002672 }
2673 //techProfile related PonAniConfigFsm FSM may be active
2674 if dh.pOnuTP != nil {
2675 // should always be the case here
2676 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 if dh.pOnuTP.PAniConfigFsm != nil {
2678 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2679 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002680 }
mpagenko900ee4b2020-10-12 11:56:34 +00002681 }
2682 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002683 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002684 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002686 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002687 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002688 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002689 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002690 } else {
2691 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002692 }
2693 }
2694 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302695
2696 dh.mutexCollectorFlag.Lock()
2697 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2698 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002699 // Stop collector routine
2700 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302701 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002702 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302703 dh.mutexCollectorFlag.Unlock()
2704
2705 dh.mutextAlarmManagerFlag.Lock()
2706 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2707 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302708 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302709 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302710 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302711 dh.mutextAlarmManagerFlag.Unlock()
2712
2713 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2714 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2715 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302717 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002718 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302719 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302720
Girish Gowdrae95687a2021-09-08 16:30:58 -07002721 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2722
mpagenko80622a52021-02-09 16:53:23 +00002723 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002724 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002725 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002726 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002728 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002729 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002730 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2731 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2732 // (even though it may also run into direct cancellation, a bit hard to verify here)
2733 // so don't set 'dh.upgradeCanceled = true' here!
2734 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2735 }
mpagenko38662d02021-08-11 09:45:19 +00002736 }
mpagenko80622a52021-02-09 16:53:23 +00002737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002739 return nil
2740}
2741
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302742//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002743func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2744 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 +05302745
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002746 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002748 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002749 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002750 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002751 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002753
mpagenkoa40e99a2020-11-17 13:50:39 +00002754 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2755 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2756 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2757 * disable/enable toggling here to allow traffic
2758 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2759 * like the py comment says:
2760 * # start by locking all the unis till mib sync and initial mib is downloaded
2761 * # this way we can capture the port down/up events when we are ready
2762 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302763
mpagenkoa40e99a2020-11-17 13:50:39 +00002764 // Init Uni Ports to Admin locked state
2765 // *** should generate UniLockStateDone event *****
2766 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002768 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002770 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002771 }
2772}
2773
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302774//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2776 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302777 /* Mib download procedure -
2778 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2779 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002781 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002783 return
2784 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002785 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302786 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 if pMibDlFsm.Is(mib.DlStDisabled) {
2788 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2789 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 +05302790 // maybe try a FSM reset and then again ... - TODO!!!
2791 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002792 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302793 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2795 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302796 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002797 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302798 //Begin MIB data download (running autonomously)
2799 }
2800 }
2801 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302804 // maybe try a FSM reset and then again ... - TODO!!!
2805 }
2806 /***** Mib download started */
2807 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302809 }
2810}
2811
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302812//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002813func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302814 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002815 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2816 if pDevEntry == nil {
2817 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2818 return
2819 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002820 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002821 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002822 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002823 // update device info in core
2824 pDevEntry.MutexPersOnuConfig.RLock()
2825 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2826 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2827 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2828 pDevEntry.MutexPersOnuConfig.RUnlock()
2829 dh.logicalDeviceID = dh.DeviceID
2830 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2831 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2832 }
2833 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002834 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2835 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2836 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2837 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002838 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002840 ConnStatus: voltha.ConnectStatus_REACHABLE,
2841 OperStatus: voltha.OperStatus_ACTIVE,
2842 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302843 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302845 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302847 }
2848 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302849 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002850 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302851 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002852 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002853
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002855 var waitForOmciProcessor sync.WaitGroup
2856 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002857 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002858 go dh.StartCollector(ctx, &waitForOmciProcessor)
2859 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002860 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 if !dh.GetAlarmManagerIsRunning(ctx) {
2862 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002863 }
2864
Girish Gowdrae95687a2021-09-08 16:30:58 -07002865 // Start flow handler routines per UNI
2866 for _, uniPort := range dh.uniEntityMap {
2867 // only if this port was enabled for use by the operator at startup
2868 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2869 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2870 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2871 }
2872 }
2873 }
2874
Girish Gowdrae0140f02021-02-02 16:55:09 -08002875 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002877 // There is no way we should be landing here, but if we do then
2878 // there is nothing much we can do about this other than log error
2879 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2880 }
2881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 pDevEntry.MutexPersOnuConfig.RLock()
2885 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2886 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302887 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002888 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002889 dh.mutexForDisableDeviceRequested.Lock()
2890 dh.disableDeviceRequested = true
2891 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002892 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002893 // reconcilement will be continued after ani config is done
2894 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002896 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002897 dh.mutexForDisableDeviceRequested.RLock()
2898 if !dh.disableDeviceRequested {
2899 if dh.pUnlockStateFsm == nil {
2900 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2901 } else { //UnlockStateFSM already init
2902 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2903 dh.runUniLockFsm(ctx, false)
2904 }
2905 dh.mutexForDisableDeviceRequested.RUnlock()
2906 } else {
2907 dh.mutexForDisableDeviceRequested.RUnlock()
2908 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002909 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302910 }
2911}
2912
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302913//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2915 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302916
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002917 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302918 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2919 if dh.GetDeviceTechProfOnReboot() {
2920 if dh.CheckForDeviceTechProf(ctx) {
2921 go dh.DeviceFlowConfigOnReboot(ctx)
2922 }
2923 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002925 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002926 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2927 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002928 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002930 return
2931 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 pDevEntry.MutexPersOnuConfig.Lock()
2933 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2934 pDevEntry.MutexPersOnuConfig.Unlock()
2935 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002938 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302939 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302940 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 +00002941 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002942 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302943
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002944 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302945
Himani Chawla26e555c2020-08-31 12:30:20 +05302946 }
2947}
2948
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302949//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002951 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002953
mpagenko44bd8362021-11-15 11:40:05 +00002954 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002955 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002957 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002958 OperStatus: voltha.OperStatus_UNKNOWN,
2959 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002960 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002962 }
2963
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002965 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002966 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002967
2968 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002972 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002974 return
2975 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 pDevEntry.MutexPersOnuConfig.Lock()
2977 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2978 pDevEntry.MutexPersOnuConfig.Unlock()
2979 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002980 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002982 }
mpagenko900ee4b2020-10-12 11:56:34 +00002983}
2984
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302985//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002987 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002989 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002991 ConnStatus: voltha.ConnectStatus_REACHABLE,
2992 OperStatus: voltha.OperStatus_ACTIVE,
2993 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002994 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002995 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002996 }
2997
dbainbri4d3a0dc2020-12-02 00:33:42 +00002998 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002999 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00003000 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00003001 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00003002
3003 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003007 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003009 return
3010 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 pDevEntry.MutexPersOnuConfig.Lock()
3012 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
3013 pDevEntry.MutexPersOnuConfig.Unlock()
3014 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003015 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003017 }
mpagenko900ee4b2020-10-12 11:56:34 +00003018}
3019
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303020//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003021func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3022 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
3023 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003024 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003025 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00003026 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003027 OperStatus: voltha.OperStatus_FAILED,
3028 }); err != nil {
3029 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
3030 }
3031}
3032
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003033func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3034 if devEvent == cmn.OmciAniConfigDone {
3035 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003036 // attention: the device reason update is done based on ONU-UNI-Port related activity
3037 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003038 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003039 // 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 +00003040 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05303041 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003043 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
3044 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
3045 dh.mutexReconcilingFirstPassFlag.Lock()
3046 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303047 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003048 dh.reconcilingFirstPass = false
3049 go dh.ReconcileDeviceFlowConfig(ctx)
3050 }
3051 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003052 }
3053 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003054 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003055 // attention: the device reason update is done based on ONU-UNI-Port related activity
3056 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003058 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3059 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003060 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003061 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303062}
3063
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003064func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003065 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303067 // attention: the device reason update is done based on ONU-UNI-Port related activity
3068 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303069
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003070 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3071 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003072 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003073 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003074 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003075 }
3076 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003078 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003079 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003080 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303081 }
mpagenkof1fc3862021-02-16 10:09:52 +00003082
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003084 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003085 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003086 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003087 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003088 }
3089 } else {
3090 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003092 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303093}
3094
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303095// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003096func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303097 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003099 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003100 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003101 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003102 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003103 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003104 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003105 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003107 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003108 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003109 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003111 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003112 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003113 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003115 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003116 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003117 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003118 case cmn.UniEnableStateFailed:
3119 {
3120 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3121 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003123 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003124 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003125 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003126 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003127 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003128 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003129 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003130 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003131 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003133 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003134 default:
3135 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003137 }
3138 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003139}
3140
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003141func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003142 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003143 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303144 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003145 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003146 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003147 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303148 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003149 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003150 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003151 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 +00003152 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003153 //store UniPort with the System-PortNumber key
3154 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003155 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003156 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003158 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003159 } //error logging already within UniPort method
3160 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303161 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003162 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003163 }
3164 }
3165}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003166
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3168 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003169 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003170 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003171 return
3172 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003173 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003175 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3176 for _, mgmtEntityID := range pptpInstKeys {
3177 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003179 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3180 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003181 }
3182 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003183 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003184 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003186 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3187 for _, mgmtEntityID := range veipInstKeys {
3188 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003189 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003190 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3191 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003192 }
3193 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003194 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003195 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003197 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3198 for _, mgmtEntityID := range potsInstKeys {
3199 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003201 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3202 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003203 }
3204 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003205 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003206 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003207 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003209 return
3210 }
3211
mpagenko2c3f6c52021-11-23 11:22:10 +00003212 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3213 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3214 // 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 -07003215 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3216 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3217 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003218 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3219 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303220 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003221 for i := 0; i < int(uniCnt); i++ {
3222 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003223 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003224 }
3225}
3226
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003227// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3228func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003229 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303230 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003231 // with following remark:
3232 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3233 // # load on the core
3234
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003235 // 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 +00003236
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003237 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003238 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003239 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3240 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303241 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003243 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003245 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003247 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 PortNo: port.PortNo,
3249 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003250 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003251 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.PortNo, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04003252 }
3253 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003254 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303255 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003256 }
mpagenko3af1f032020-06-10 08:53:41 +00003257 }
3258 }
3259}
3260
3261// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003262func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3263 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003264 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3265 for uniNo, uniPort := range dh.uniEntityMap {
3266 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003267
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3269 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303270 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003272 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003274 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003275 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003276 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003277 PortNo: port.PortNo,
3278 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003279 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003280 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 -04003281 }
3282 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003283 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303284 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003285 }
3286
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003287 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003288 }
3289}
3290
3291// ONU_Active/Inactive announcement on system KAFKA bus
3292// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303293func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003294 var de voltha.DeviceEvent
3295 eventContext := make(map[string]string)
3296 //Populating event context
3297 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003298 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003299 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003300 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003301 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003302 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 +00003303 }
3304 oltSerialNumber := parentDevice.SerialNumber
3305
3306 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3307 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3308 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303309 eventContext["olt-serial-number"] = oltSerialNumber
3310 eventContext["device-id"] = aDeviceID
3311 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003312 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003313 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3314 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003315 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3316 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003317 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3318 deviceEntry.MutexPersOnuConfig.RUnlock()
3319 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003320 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003321 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3322 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3323 } else {
3324 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3325 log.Fields{"device-id": aDeviceID})
3326 return
3327 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003328
3329 /* Populating device event body */
3330 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303331 de.ResourceId = aDeviceID
3332 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003333 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3334 de.Description = fmt.Sprintf("%s Event - %s - %s",
3335 cEventObjectType, cOnuActivatedEvent, "Raised")
3336 } else {
3337 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3338 de.Description = fmt.Sprintf("%s Event - %s - %s",
3339 cEventObjectType, cOnuActivatedEvent, "Cleared")
3340 }
3341 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303342 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003343 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303344 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003345 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303346 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303347 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003348}
3349
Himani Chawla4d908332020-08-31 12:30:20 +05303350// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303352 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003353 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303354 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003355 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003356 sFsmName = "LockStateFSM"
3357 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003359 sFsmName = "UnLockStateFSM"
3360 }
mpagenko3af1f032020-06-10 08:53:41 +00003361
bseenivacfcd8f72026-01-30 21:06:49 +05303362 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00003363 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003364 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003365 return
3366 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003367 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003368 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303369 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003370 dh.pLockStateFsm = pLSFsm
3371 } else {
3372 dh.pUnlockStateFsm = pLSFsm
3373 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003374 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003375 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003376 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003377 }
3378}
3379
3380// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003381func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003382 /* Uni Port lock/unlock procedure -
3383 ***** should run via 'adminDone' state and generate the argument requested event *****
3384 */
3385 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303386 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003387 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003388 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3389 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3391 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003392 }
3393 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003395 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3396 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3398 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003399 }
3400 }
3401 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3403 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003404 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003405 // maybe try a FSM reset and then again ... - TODO!!!
3406 } else {
3407 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003408 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003409 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003410 }
3411 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003412 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003413 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003414 // maybe try a FSM reset and then again ... - TODO!!!
3415 }
3416 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003417 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003418 // maybe try a FSM reset and then again ... - TODO!!!
3419 }
3420}
3421
mpagenko80622a52021-02-09 16:53:23 +00003422// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003423// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303424//
3425//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303427 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003428 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003430 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303432 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003433 }
bseeniva0b4286b2026-01-30 13:05:42 +05303434 fsmCtx := log.WithSpanFromContext(context.Background(), ctx)
3435 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(fsmCtx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003436 sFsmName, chUpgradeFsm)
3437 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003439 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003440 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3441 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003442 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003443 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303444 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003445 }
mpagenko59862f02021-10-11 08:53:18 +00003446 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003447 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3448 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003449 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3450 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003451 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003453 } else {
3454 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003456 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303457 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003458 }
3459 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003461 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303462 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003463 }
3464 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303466 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003467 }
3468 return nil
3469}
3470
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003471// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3472func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003473 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003475 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003476 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3477 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003478 dh.pLastUpgradeImageState = apImageState
3479 dh.lockUpgradeFsm.Unlock()
3480 //signal upgradeFsm removed using non-blocking channel send
3481 select {
3482 case dh.upgradeFsmChan <- struct{}{}:
3483 default:
3484 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003485 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003486 }
mpagenko80622a52021-02-09 16:53:23 +00003487}
3488
mpagenko15ff4a52021-03-02 10:09:20 +00003489// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3490func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003491 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003492 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003494 return
3495 }
3496
3497 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003498 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003499 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003500 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3501 dh.lockUpgradeFsm.RUnlock()
3502 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3503 return
3504 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003505 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003506 if pUpgradeStatemachine != nil {
3507 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3508 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509 UpgradeState := pUpgradeStatemachine.Current()
3510 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3511 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3512 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003513 // 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 +00003514 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003515 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3516 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003517 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003518 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003520 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3521 dh.upgradeCanceled = true
3522 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3523 }
mpagenko15ff4a52021-03-02 10:09:20 +00003524 return
3525 }
mpagenko59862f02021-10-11 08:53:18 +00003526 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3528 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003529 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003530 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003531 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3532 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003533 return
3534 }
3535 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003537 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3539 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003540 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3541 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003542 return
3543 }
3544 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003545 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003546 }
3547 } else {
3548 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 +00003549 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003550 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3551 dh.upgradeCanceled = true
3552 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3553 }
mpagenko1f8e8822021-06-25 14:10:21 +00003554 }
mpagenko15ff4a52021-03-02 10:09:20 +00003555 return
3556 }
mpagenko59862f02021-10-11 08:53:18 +00003557 dh.lockUpgradeFsm.RUnlock()
3558 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3559 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003560 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3561 dh.upgradeCanceled = true
3562 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3563 }
mpagenko59862f02021-10-11 08:53:18 +00003564 return
3565 }
3566 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3567 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3568 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3569 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3570 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3571 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3572 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003573 }
mpagenko15ff4a52021-03-02 10:09:20 +00003574 }
3575 }
3576 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003578 }
mpagenko59862f02021-10-11 08:53:18 +00003579 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003580}
3581
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303582// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003584
3585 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003586 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003587 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003588 kvbackend := &db.Backend{
3589 Client: dh.pOpenOnuAc.kvClient,
3590 StoreType: dh.pOpenOnuAc.KVStoreType,
3591 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003592 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003593 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3594 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003595
mpagenkoaf801632020-07-03 10:00:42 +00003596 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003597}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303598
3599//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003600func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303601 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003602
mpagenkodff5dda2020-08-28 11:52:01 +00003603 for _, field := range flow.GetOfbFields(apFlowItem) {
3604 switch field.Type {
3605 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3606 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003608 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3609 }
mpagenko01e726e2020-10-23 09:45:29 +00003610 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003611 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3612 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303613 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303615 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3616 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003617 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3618 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003619 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003620 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303621 return
mpagenkodff5dda2020-08-28 11:52:01 +00003622 }
3623 }
mpagenko01e726e2020-10-23 09:45:29 +00003624 */
mpagenkodff5dda2020-08-28 11:52:01 +00003625 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3626 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303627 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003628 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303629 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3630 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303631 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003633 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303634 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003635 }
3636 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3637 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303638 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003639 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303640 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003641 }
3642 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3643 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003644 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003645 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3646 }
3647 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3648 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003650 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3651 }
3652 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3653 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003654 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003655 "IPv4-DST": field.GetIpv4Dst()})
3656 }
3657 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3658 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003659 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003660 "IPv4-SRC": field.GetIpv4Src()})
3661 }
3662 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3663 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003664 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003665 "Metadata": field.GetTableMetadata()})
3666 }
3667 /*
3668 default:
3669 {
3670 //all other entires ignored
3671 }
3672 */
3673 }
3674 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303675}
mpagenkodff5dda2020-08-28 11:52:01 +00003676
khenaidoo7d3c5582021-08-11 18:09:44 -04003677func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003678 for _, action := range flow.GetActions(apFlowItem) {
3679 switch action.Type {
3680 /* not used:
3681 case of.OfpActionType_OFPAT_OUTPUT:
3682 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003683 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003684 "Output": action.GetOutput()})
3685 }
3686 */
3687 case of.OfpActionType_OFPAT_PUSH_VLAN:
3688 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003689 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003690 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3691 }
3692 case of.OfpActionType_OFPAT_SET_FIELD:
3693 {
3694 pActionSetField := action.GetSetField()
3695 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003697 "OxcmClass": pActionSetField.Field.OxmClass})
3698 }
3699 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303700 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003701 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303702 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003703 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303704 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303706 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003707 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003708 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003709 "Type": pActionSetField.Field.GetOfbField().Type})
3710 }
3711 }
3712 /*
3713 default:
3714 {
3715 //all other entires ignored
3716 }
3717 */
3718 }
3719 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303720}
3721
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303722// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003723func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003724 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303725 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3726 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303727 var loSetPcp uint8
3728 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303729 var loIPProto uint32
3730 /* the TechProfileId is part of the flow Metadata - compare also comment within
3731 * OLT-Adapter:openolt_flowmgr.go
3732 * Metadata 8 bytes:
3733 * Most Significant 2 Bytes = Inner VLAN
3734 * Next 2 Bytes = Tech Profile ID(TPID)
3735 * Least Significant 4 Bytes = Port ID
3736 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3737 * subscriber related flows.
3738 */
3739
dbainbri4d3a0dc2020-12-02 00:33:42 +00003740 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303741 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003742 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003743 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003744 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303745 }
mpagenko551a4d42020-12-08 18:09:20 +00003746 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003747 loCookie := apFlowItem.GetCookie()
3748 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303749 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003750 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303751 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303752
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303753 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003754 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303755 if loIPProto == 2 {
3756 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3757 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003758 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303760 return nil
3761 }
mpagenko01e726e2020-10-23 09:45:29 +00003762 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003763 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003764
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303765 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3766 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003767 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003768 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003769 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3770 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3771 //TODO!!: Use DeviceId within the error response to rwCore
3772 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003773 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003774 }
3775 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003777 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303778 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3779 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3780 loSetVlan = loMatchVlan
3781 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 +00003782 } else {
3783 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3784 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3785 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303786 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003787 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003788 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003789 }
mpagenko9a304ea2020-12-16 15:54:01 +00003790
khenaidoo42dcdfd2021-10-19 17:34:12 -04003791 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003792 if apFlowMetaData != nil {
3793 meter = apFlowMetaData.Meters[0]
3794 }
mpagenkobc4170a2021-08-17 16:42:10 +00003795 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3796 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3797 // when different rules are requested concurrently for the same uni
3798 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3799 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3800 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003801 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3802 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003803 //SetUniFlowParams() may block on some rule that is suspended-to-add
3804 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003805 // Also the error is returned to caller via response channel
3806 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303807 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003808 dh.lockVlanConfig.RUnlock()
3809 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003810 return
mpagenkodff5dda2020-08-28 11:52:01 +00003811 }
mpagenkobc4170a2021-08-17 16:42:10 +00003812 dh.lockVlanConfig.RUnlock()
3813 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003814 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303815 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003816 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003817 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003818 if err != nil {
3819 *respChan <- err
3820 }
mpagenko01e726e2020-10-23 09:45:29 +00003821}
3822
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303823// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003824func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003825 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3826 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3827 //no extra check is done on the rule parameters
3828 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3829 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3830 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3831 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003832 // - 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 +00003833 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003834 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003835
3836 /* TT related temporary workaround - should not be needed anymore
3837 for _, field := range flow.GetOfbFields(apFlowItem) {
3838 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3839 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003841 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3842 if loIPProto == 2 {
3843 // 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 +00003844 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003846 return nil
3847 }
3848 }
3849 } //for all OfbFields
3850 */
3851
mpagenko9a304ea2020-12-16 15:54:01 +00003852 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003853 dh.lockVlanConfig.RLock()
3854 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003855 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3856 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003857 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3858 return
mpagenko01e726e2020-10-23 09:45:29 +00003859 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003860 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003862 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003863 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003864 // Push response on the response channel
3865 if respChan != nil {
3866 // 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
3867 select {
3868 case *respChan <- nil:
3869 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3870 default:
3871 }
3872 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003873 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003874}
3875
Himani Chawla26e555c2020-08-31 12:30:20 +05303876// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003877// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003878// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003879func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303880 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 +05303881 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003882
bseenivacfcd8f72026-01-30 21:06:49 +05303883 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkodff5dda2020-08-28 11:52:01 +00003884 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3886 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003887 }
3888
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303889 if dh.pDeviceStateFsm.Current() == devStDown {
3890 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3891 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3892 }
3893
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3895 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303896 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003897 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003898 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3899 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003900 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3901 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003902 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3904 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003905 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3906 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003907 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003908 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303909 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003910 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003911 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3912 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003913 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003914 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3916 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003917 }
3918 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003919 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003920 "device-id": dh.DeviceID})
3921 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003922 }
3923 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003924 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3926 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003927 }
3928 return nil
3929}
3930
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303931// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003932// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003933func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003934 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003935 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003936 for _, uniPort := range dh.uniEntityMap {
3937 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003938 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003939 pCurrentUniPort = uniPort
3940 break //found - end search loop
3941 }
3942 }
3943 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003944 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003945 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003946 return
3947 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003948 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003949}
3950
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303951// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003952func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003953 //TODO!! verify and start pending flow configuration
3954 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3955 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303956 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003957 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003958 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003959 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003960 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003961 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003962 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003963 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003964 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003965 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3966 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003967 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003968 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003969 } else {
3970 /***** UniVlanConfigFsm continued */
3971 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003972 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3973 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003974 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003975 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3976 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003977 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003978 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003979 } else {
3980 /***** UniVlanConfigFsm continued */
3981 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003982 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3983 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003984 }
mpagenkodff5dda2020-08-28 11:52:01 +00003985 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003986 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003987 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3988 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003989 }
3990 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003991 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 +00003992 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3993 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003994 }
3995 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003996 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003997 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003998 }
mpagenkof1fc3862021-02-16 10:09:52 +00003999 } else {
4000 dh.lockVlanConfig.RUnlock()
4001 }
mpagenkodff5dda2020-08-28 11:52:01 +00004002}
4003
Akash Soni3de0e062024-12-11 16:37:26 +05304004// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
4005func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
4006 dh.lockVlanConfig.Lock()
4007 defer dh.lockVlanConfig.Unlock()
4008
4009 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
4010 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
4011 if pVlanFilterStatemachine != nil {
4012 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4013 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
4014 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
4015 })
4016 } else {
4017 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
4018 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
4019 })
4020 }
4021 } else {
4022 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
4023 "device-id": dh.DeviceID, "UniPort": uniID,
4024 })
4025 }
4026 } else {
4027 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
4028 "device-id": dh.DeviceID, "UniPort": uniID,
4029 })
4030 }
4031}
4032
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304033// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00004034// 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 +00004035func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004036 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004038 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00004039 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004040 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00004041 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00004042}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004043
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304044// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004045func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00004046 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
4047 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
4048 // obviously then parallel processing on the cancel must be avoided
4049 // deadline context to ensure completion of background routines waited for
4050 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4051 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4052 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304053 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004054
Akash Soni840f8d62024-12-11 19:37:06 +05304055 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4056 if err != nil {
4057 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4058 return err
4059 }
4060 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004061}
4062
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304063// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4064// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004065func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4066 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004067
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004068 if dh.IsReconciling() {
bseeniva8c4547f2026-01-30 16:30:30 +05304069 logger.Debug(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004070 return nil
4071 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004072 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004073
bseenivacfcd8f72026-01-30 21:06:49 +05304074 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004075 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004076 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4077 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004078 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004080
mpagenkof1fc3862021-02-16 10:09:52 +00004081 if aWriteToKvStore {
4082 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4083 }
4084 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004085}
4086
dbainbri4d3a0dc2020-12-02 00:33:42 +00004087func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004088 defer cancel() //ensure termination of context (may be pro forma)
4089 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004090 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004091 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004092}
4093
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304094// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4095//
4096// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004097func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4098 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4099 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4100 dh.mutexDeviceReason.Lock()
4101 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004102 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004103 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004104 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004105 DeviceId: dh.DeviceID,
4106 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004107 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004108 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004109 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004110 return err
4111 }
mpagenkoe4782082021-11-25 12:04:26 +00004112 } else {
4113 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 +00004114 }
mpagenkoe4782082021-11-25 12:04:26 +00004115 dh.deviceReason = deviceReason
4116 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4117 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004118 return nil
4119}
4120
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004121func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
bseenivacfcd8f72026-01-30 21:06:49 +05304122 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004123 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004124 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4125 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004126 }
mpagenkof1fc3862021-02-16 10:09:52 +00004127 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004128}
4129
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304130func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4131 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4132 if pDevEntry != nil {
4133 pDevEntry.MutexPersOnuConfig.Lock()
4134 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4135 pDevEntry.MutexPersOnuConfig.Unlock()
4136 } else {
4137 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4138 }
4139}
4140
4141func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4142 rebootFlag := false
4143 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4144 if pDevEntry != nil {
4145 pDevEntry.MutexPersOnuConfig.RLock()
4146 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4147 pDevEntry.MutexPersOnuConfig.RUnlock()
4148 } else {
4149 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4150 }
4151 return rebootFlag
4152}
4153
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004154// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004155// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004156func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4157 dh.lockDevice.RLock()
4158 defer dh.lockDevice.RUnlock()
4159 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004160 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004161 }
4162 return 0, errors.New("error-fetching-uni-port")
4163}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004164
4165// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004166func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4167 var errorsList []error
4168 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 -08004169
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004170 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4171 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4172 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4173
4174 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4175 // successfully.
4176 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4177 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4178 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004179 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 -08004180 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004181 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004182 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004183 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004184}
4185
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004186func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4187 var err error
4188 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004189 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004190
4191 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004193 errorsList = append(errorsList, err)
4194 }
4195 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004196 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004197
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004198 return errorsList
4199}
4200
4201func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4202 var err error
4203 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004204 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004205 // Check if group metric related config is updated
4206 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004207 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4208 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4209 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004210
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004211 if ok && m.Frequency != v.GroupFreq {
4212 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004213 errorsList = append(errorsList, err)
4214 }
4215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004216 if ok && m.Enabled != v.Enabled {
4217 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004218 errorsList = append(errorsList, err)
4219 }
4220 }
4221 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004222 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004223 return errorsList
4224}
4225
4226func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4227 var err error
4228 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004229 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004230 // Check if standalone metric related config is updated
4231 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004232 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4233 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4234 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004235
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004236 if ok && m.Frequency != v.SampleFreq {
4237 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004238 errorsList = append(errorsList, err)
4239 }
4240 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004241 if ok && m.Enabled != v.Enabled {
4242 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004243 errorsList = append(errorsList, err)
4244 }
4245 }
4246 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004247 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004248 return errorsList
4249}
4250
4251// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004252func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004253 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304254 dh.RLockMutexDeletionInProgressFlag()
4255 if dh.GetDeletionInProgress() {
4256 logger.Warnw(ctx, "Device deletion in progress - avoid starting metrics collector routine", log.Fields{"device-id": dh.device.Id})
4257 dh.RUnlockMutexDeletionInProgressFlag()
4258 return
4259 }
4260 // Set collectorIsRunning flag to true while still holding deviceDeletionFlag lock,
4261 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the collector routine if this flag is not yet set
4262 dh.setCollectorIsRunning(true)
4263 dh.RUnlockMutexDeletionInProgressFlag()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004264
4265 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004266 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304267 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004268 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004269 // Initialize the next metric collection time.
4270 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4271 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004272 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304273 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4274 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004275 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304276
Girish Gowdrae09a6202021-01-12 18:10:59 -08004277 select {
4278 case <-dh.stopCollector:
4279 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004280 // Stop the L2 PM FSM
4281 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004282 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4283 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4284 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004285 }
4286 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004287 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004288 }
4289 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004290 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4291 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004292 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004293 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4294 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004295 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004296
Girish Gowdrae09a6202021-01-12 18:10:59 -08004297 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304298 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004299 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4300 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4301 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4302 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004303 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004304 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4305 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004306 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004307 } else {
4308 if dh.pmConfigs.Grouped { // metrics are managed as a group
4309 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004310 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004311
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004312 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4313 // 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 -08004314 // 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 +00004315 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4316 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004317 }
4318 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004319 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4320 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4321 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4322 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004323 }
4324 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004325 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004326
4327 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004328 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4329 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4330 // 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 -08004331 // 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 +00004332 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004333 prevInternal := g.NextCollectionInterval
4334 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004335 }
4336 }
4337 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004338 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4339 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4340 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004341 prevInternal := m.NextCollectionInterval
4342 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004343 }
4344 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004345 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004346 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004347 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004348 } */
4349 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004350 }
4351 }
4352}
kesavandfdf77632021-01-26 23:40:33 -05004353
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304354//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304355func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4356
4357 singleValResp := extension.SingleSetValueResponse{
4358 Response: &extension.SetValueResponse{
4359 Status: extension.SetValueResponse_OK,
4360 },
4361 }
4362
4363 return &singleValResp
4364}
4365
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004366func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004367
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004368 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4369 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004370}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004371
Himani Chawla43f95ff2021-06-03 00:24:12 +05304372func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4373 if dh.pOnuMetricsMgr == nil {
4374 return &extension.SingleGetValueResponse{
4375 Response: &extension.GetValueResponse{
4376 Status: extension.GetValueResponse_ERROR,
4377 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4378 },
4379 }
4380 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304381 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304382 return resp
4383}
4384
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004385func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4386
4387 var err error
4388 var pDevOmciCC *cmn.OmciCC
4389 if dh.pOnuOmciDevice == nil {
4390 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4391 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4392 } else {
4393 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4394 if pDevOmciCC == nil {
4395 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4396 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4397 }
4398 }
4399 if err != nil {
4400 return &extension.SingleGetValueResponse{
4401 Response: &extension.GetValueResponse{
4402 Status: extension.GetValueResponse_ERROR,
4403 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4404 },
4405 },
4406 err
4407 }
4408 return pDevOmciCC.GetOmciCounters(), nil
4409}
4410
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304411//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004412func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4413 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004414 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004415 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004416 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004417}
4418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004419func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004420 var pAdapterFsm *cmn.AdapterFsm
4421 //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 +00004422 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004423 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004424 {
mpagenkofbf577d2021-10-12 11:44:33 +00004425 if dh.pOnuOmciDevice != nil {
4426 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4427 } else {
4428 return true //FSM not active - so there is no activity on omci
4429 }
mpagenkof1fc3862021-02-16 10:09:52 +00004430 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004431 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004432 {
mpagenkofbf577d2021-10-12 11:44:33 +00004433 if dh.pOnuOmciDevice != nil {
4434 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
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.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004440 {
mpagenkofbf577d2021-10-12 11:44:33 +00004441 if dh.pLockStateFsm != nil {
4442 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
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.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004448 {
mpagenkofbf577d2021-10-12 11:44:33 +00004449 if dh.pUnlockStateFsm != nil {
4450 pAdapterFsm = dh.pUnlockStateFsm.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.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004456 {
mpagenkofbf577d2021-10-12 11:44:33 +00004457 if dh.pOnuMetricsMgr != nil {
4458 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004459 } else {
4460 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004461 }
4462 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004463 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004464 {
4465 dh.lockUpgradeFsm.RLock()
4466 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004467 if dh.pOnuUpradeFsm != nil {
4468 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4469 } else {
4470 return true //FSM not active - so there is no activity on omci
4471 }
mpagenko80622a52021-02-09 16:53:23 +00004472 }
mpagenkof1fc3862021-02-16 10:09:52 +00004473 default:
4474 {
4475 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004476 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004477 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004478 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004479 }
mpagenkofbf577d2021-10-12 11:44:33 +00004480 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4481 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4482 }
4483 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004484}
4485
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004486func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4487 for _, v := range dh.pOnuTP.PAniConfigFsm {
4488 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004489 return false
4490 }
4491 }
4492 return true
4493}
4494
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304495//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004496func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004497 dh.lockVlanConfig.RLock()
4498 defer dh.lockVlanConfig.RUnlock()
4499 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004500 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004501 return false
4502 }
4503 }
4504 return true //FSM not active - so there is no activity on omci
4505}
4506
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304507//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004508func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4509 dh.lockVlanConfig.RLock()
4510 defer dh.lockVlanConfig.RUnlock()
4511 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004512 if v.PAdaptFsm.PFsm != nil {
4513 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004514 return true //there is at least one VLAN FSM with some active configuration
4515 }
4516 }
4517 }
4518 return false //there is no VLAN FSM with some active configuration
4519}
4520
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004521func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004522 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4523 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4524 return false
4525 }
4526 }
4527 // a further check is done to identify, if at least some data traffic related configuration exists
4528 // 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])
4529 return dh.checkUserServiceExists(ctx)
4530}
4531
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004532func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304533 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 +00004534 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004535 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004536 // TODO: fatal error reset ONU, delete deviceHandler!
4537 return
4538 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004539 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4540 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004541}
4542
4543func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4544 dh.mutexCollectorFlag.Lock()
4545 dh.collectorIsRunning = flagValue
4546 dh.mutexCollectorFlag.Unlock()
4547}
4548
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004549func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004550 dh.mutexCollectorFlag.RLock()
4551 flagValue := dh.collectorIsRunning
4552 dh.mutexCollectorFlag.RUnlock()
4553 return flagValue
4554}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304555
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304556func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4557 dh.mutextAlarmManagerFlag.Lock()
4558 dh.alarmManagerIsRunning = flagValue
4559 dh.mutextAlarmManagerFlag.Unlock()
4560}
4561
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004562func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304563 dh.mutextAlarmManagerFlag.RLock()
4564 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004565 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304566 dh.mutextAlarmManagerFlag.RUnlock()
4567 return flagValue
4568}
4569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004570func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004571 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304572 dh.RLockMutexDeletionInProgressFlag()
4573 if dh.GetDeletionInProgress() {
4574 logger.Warnw(ctx, "Device deletion in progress - avoid starting alarm manager", log.Fields{"device-id": dh.DeviceID})
4575 dh.RUnlockMutexDeletionInProgressFlag()
4576 return
4577 }
4578 // Set alarmManagerIsRunning flag to true while still holding deviceDeletionFlag lock,
4579 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the alarm manager if this flag is not yet set
4580 dh.setAlarmManagerIsRunning(true)
4581
4582 dh.RUnlockMutexDeletionInProgressFlag()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304583
4584 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004585 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304586 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304587 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304588 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004589 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4590 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304591 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304592 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004593 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4594 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304595 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304596 }
4597}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004598
Girish Gowdrae95687a2021-09-08 16:30:58 -07004599func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4600 dh.mutexFlowMonitoringRoutineFlag.Lock()
4601 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004602 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004603 dh.isFlowMonitoringRoutineActive[uniID] = flag
4604}
4605
4606func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4607 dh.mutexFlowMonitoringRoutineFlag.RLock()
4608 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4609 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004610 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304611 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4612 return dh.isFlowMonitoringRoutineActive[uniID]
4613 }
4614 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004615}
4616
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004617func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304618 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004619
Maninder7961d722021-06-16 22:10:28 +05304620 connectStatus := voltha.ConnectStatus_UNREACHABLE
4621 operState := voltha.OperStatus_UNKNOWN
4622
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004623 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004624 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004625 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004626 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004627 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004628 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304629 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004630 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4631 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4632 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4633 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4634 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4635 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4636 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4637 // However, a later refactoring of the functionality remains unaffected.
4638 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004639 if success {
bseenivacfcd8f72026-01-30 21:06:49 +05304640 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304641 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004642 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304643 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004644 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304645 switch onuDevEntry.SOnuPersistentData.PersOperState {
4646 case "up":
Maninderb5187552021-03-23 22:23:42 +05304647 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004648 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4649 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304650 operState = voltha.OperStatus_ACTIVE
4651 } else {
4652 operState = voltha.OperStatus_ACTIVATING
4653 }
4654 }
mgoudad611f4c2025-10-30 14:49:27 +05304655 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304656 operState = voltha.OperStatus_DISCOVERED
4657 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004658 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004659 logger.Debugw(ctx, "Core DeviceStateUpdate",
4660 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304661 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304662 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004663 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004664 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004665 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004666 ConnStatus: connectStatus,
4667 OperStatus: operState,
4668 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304669 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004670 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304671 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004672 } else {
Maninderb5187552021-03-23 22:23:42 +05304673 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004674 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304675
bseenivacfcd8f72026-01-30 21:06:49 +05304676 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304677 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004678 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004679 } else {
4680 onuDevEntry.MutexPersOnuConfig.RLock()
4681 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4682 connectStatus = voltha.ConnectStatus_REACHABLE
4683 }
4684 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304685 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004686 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004687 }
mpagenko101ac942021-11-16 15:01:29 +00004688 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004689 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004690 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004691 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304692
bseenivacfcd8f72026-01-30 21:06:49 +05304693 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304694 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004695 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004696 } else {
4697 onuDevEntry.MutexPersOnuConfig.RLock()
4698 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4699 connectStatus = voltha.ConnectStatus_REACHABLE
4700 }
4701 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304702 }
4703
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004704 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304705
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004706 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004707 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004708 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004709 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004710 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004711
bseenivacfcd8f72026-01-30 21:06:49 +05304712 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004713 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4714 } else {
4715 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304716 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004717 onuDevEntry.MutexReconciledTpInstances.Unlock()
4718 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004719 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004720 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004721 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304722 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004723 dh.reconciling = cSkipOnuConfigReconciling
4724 } else {
4725 dh.reconciling = cOnuConfigReconciling
4726 }
4727 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004728}
4729
mpagenko101ac942021-11-16 15:01:29 +00004730func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304731 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004732 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004733 dh.sendChReconcileFinished(success)
4734 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4735 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4736 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004737 } else {
mpagenko101ac942021-11-16 15:01:29 +00004738 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004739 }
4740}
4741
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004742func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004743 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004744 defer dh.mutexReconcilingFlag.RUnlock()
4745 return dh.reconciling != cNoReconciling
4746}
4747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004748func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004749 dh.mutexReconcilingFlag.RLock()
4750 defer dh.mutexReconcilingFlag.RUnlock()
4751 return dh.reconciling == cSkipOnuConfigReconciling
4752}
4753
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004754func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4755 dh.mutexReconcilingFirstPassFlag.Lock()
4756 dh.reconcilingFirstPass = value
4757 dh.mutexReconcilingFirstPassFlag.Unlock()
4758}
4759
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004760func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4761 dh.mutexReconcilingReasonUpdate.Lock()
4762 dh.reconcilingReasonUpdate = value
4763 dh.mutexReconcilingReasonUpdate.Unlock()
4764}
4765
4766func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4767 dh.mutexReconcilingReasonUpdate.RLock()
4768 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4769 return dh.reconcilingReasonUpdate
4770}
4771
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004772func (dh *deviceHandler) getDeviceReason() uint8 {
4773 dh.mutexDeviceReason.RLock()
4774 value := dh.deviceReason
4775 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004776 return value
4777}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004778
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004779func (dh *deviceHandler) GetDeviceReasonString() string {
4780 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004781}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004783func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004784 dh.mutexReadyForOmciConfig.Lock()
4785 dh.readyForOmciConfig = flagValue
4786 dh.mutexReadyForOmciConfig.Unlock()
4787}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004788func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004789 dh.mutexReadyForOmciConfig.RLock()
4790 flagValue := dh.readyForOmciConfig
4791 dh.mutexReadyForOmciConfig.RUnlock()
4792 return flagValue
4793}
Maninder7961d722021-06-16 22:10:28 +05304794
4795func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004796 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304797 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004798 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304799 }
4800
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004801 logger.Debugw(ctx, "Core DeviceStateUpdate",
4802 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004803 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004804 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004805 ConnStatus: connectStatus,
4806 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4807 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304808 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004809 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304810 }
bseeniva4714cee2026-01-30 16:21:47 +05304811 context := make(map[string]string)
4812 context["device-id"] = dh.DeviceID
4813 context["onu-serial-number"] = dh.device.SerialNumber
4814 context["parent-id"] = dh.parentID
4815
4816 deviceEvent := &voltha.DeviceEvent{
4817 ResourceId: dh.DeviceID,
4818 DeviceEventName: cmn.OnuReconcileFailed,
4819 Description: cmn.OnuReconcileFailedAbortedDesc,
4820 Context: context,
4821 }
4822 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4823 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
Maninder7961d722021-06-16 22:10:28 +05304824}
khenaidoo7d3c5582021-08-11 18:09:44 -04004825
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304826func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4827 if techProfInstLoadFailed {
4828 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4829 logger.Errorw(ctx, "unable to update device reason to core",
4830 log.Fields{"device-id": dh.DeviceID, "Err": err})
4831 }
4832 context := make(map[string]string)
4833 context["device-id"] = dh.DeviceID
4834 context["onu-serial-number"] = dh.device.SerialNumber
4835 context["parent-id"] = dh.parentID
4836
4837 // Send event on flow configuration failure so that corrective action can be triggered from NB
4838 deviceEvent := &voltha.DeviceEvent{
4839 ResourceId: dh.DeviceID,
4840 DeviceEventName: cmn.OnuFlowConfigFailed,
4841 Description: cmn.OnuFlowConfigFailedDesc,
4842 Context: context,
4843 }
4844 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4845 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4846 }
4847}
4848
khenaidoo7d3c5582021-08-11 18:09:44 -04004849/*
4850Helper functions to communicate with Core
4851*/
4852
4853func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4854 cClient, err := dh.coreClient.GetCoreServiceClient()
4855 if err != nil || cClient == nil {
4856 return nil, err
4857 }
4858 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4859 defer cancel()
4860 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304861 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004862}
4863
khenaidoo42dcdfd2021-10-19 17:34:12 -04004864func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004865 cClient, err := dh.coreClient.GetCoreServiceClient()
4866 if err != nil || cClient == nil {
4867 return err
4868 }
4869 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4870 defer cancel()
4871 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004872 logger.Debugw(subCtx, "device-updated-in-core",
4873 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004874 return err
4875}
4876
4877func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4878 cClient, err := dh.coreClient.GetCoreServiceClient()
4879 if err != nil || cClient == nil {
4880 return err
4881 }
4882 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4883 defer cancel()
4884 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004885 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4886 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004887 return err
4888}
4889
4890func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4891 cClient, err := dh.coreClient.GetCoreServiceClient()
4892 if err != nil || cClient == nil {
4893 return err
4894 }
4895 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4896 defer cancel()
4897 _, err = cClient.DeviceUpdate(subCtx, device)
4898 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4899 return err
4900}
4901
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004902func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004903 cClient, err := dh.coreClient.GetCoreServiceClient()
4904 if err != nil || cClient == nil {
4905 return err
4906 }
4907 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4908 defer cancel()
4909 _, err = cClient.PortCreated(subCtx, port)
4910 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4911 return err
4912}
4913
khenaidoo42dcdfd2021-10-19 17:34:12 -04004914func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004915 cClient, err := dh.coreClient.GetCoreServiceClient()
4916 if err != nil || cClient == nil {
4917 return err
4918 }
4919 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4920 defer cancel()
4921 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004922 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 -04004923 return err
4924}
4925
khenaidoo42dcdfd2021-10-19 17:34:12 -04004926func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004927 cClient, err := dh.coreClient.GetCoreServiceClient()
4928 if err != nil || cClient == nil {
4929 return err
4930 }
4931 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4932 defer cancel()
4933 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004934 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 -04004935 return err
4936}
4937
4938/*
4939Helper functions to communicate with parent adapter
4940*/
4941
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004942func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4943 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4944
4945 var request = ia.TechProfileInstanceRequestMessage{
4946 DeviceId: dh.DeviceID,
4947 TpInstancePath: aTpPath,
4948 ParentDeviceId: dh.parentID,
4949 ParentPonPort: dh.device.ParentPortNo,
4950 OnuId: dh.device.ProxyAddress.OnuId,
4951 UniId: uint32(aUniID),
4952 }
4953
4954 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004955 if err != nil || pgClient == nil {
4956 return nil, err
4957 }
4958 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4959 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004960 logger.Debugw(subCtx, "get-tech-profile-instance",
4961 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004962 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004963}
4964
Girish Gowdrae95687a2021-09-08 16:30:58 -07004965// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4966// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4967func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
bseeniva8c4547f2026-01-30 16:30:30 +05304968 logger.Debugw(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004969 dh.setFlowMonitoringIsRunning(uniID, true)
4970 for {
4971 select {
4972 // block on the channel to receive an incoming flow
4973 // process the flow completely before proceeding to handle the next flow
4974 case flowCb := <-dh.flowCbChan[uniID]:
4975 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304976 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004977 respChan := make(chan error)
4978 if flowCb.addFlow {
4979 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4980 } else {
4981 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4982 }
4983 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304984 select {
4985
4986 case msg := <-respChan:
4987 *flowCb.respChan <- msg
4988 // response sent successfully
4989 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4990 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4991 case <-flowCb.ctx.Done():
4992 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4993 // Optionally, you can handle cleanup or logging here
4994 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4995 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4996 if pVlanFilterStatemachine != nil {
4997
4998 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4999 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
5000 log.Fields{"device-id": dh.DeviceID, "err": err})
5001
5002 }
5003
5004 }
5005 }
5006
5007 ctx2 := context.Background()
5008 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
5009 if metadata == 0 {
5010 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
5011 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5012 continue
5013 }
5014 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
5015
5016 if TpID == uint16(0) {
5017 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
5018 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5019 continue
5020 }
5021 if dh.pOnuTP != nil {
5022 // should always be the case here
5023 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
5024 if dh.pOnuTP.PAniConfigFsm != nil {
5025 uniTP := avcfg.UniTP{
5026 UniID: flowCb.uniPort.UniID,
5027 TpID: uint8(TpID),
5028 }
5029 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
5030 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
5031 }
5032 }
5033 }
5034
5035 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07005036 case <-dh.stopFlowMonitoringRoutine[uniID]:
5037 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
5038 dh.setFlowMonitoringIsRunning(uniID, false)
5039 return
5040 }
5041 }
5042}
5043
kesavand011d5162021-11-25 19:21:06 +05305044func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
5045 request.ParentDeviceId = dh.GetProxyAddressID()
5046 request.ChildDeviceId = dh.DeviceID
5047 request.ProxyAddress = dh.GetProxyAddress()
5048 request.ConnectStatus = common.ConnectStatus_REACHABLE
5049
5050 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5051 if err != nil || pgClient == nil {
5052 return err
5053 }
5054 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5055 defer cancel()
5056 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
5057 _, err = pgClient.ProxyOmciRequests(subCtx, request)
5058 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00005059 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
5060 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05305061 }
5062 return err
5063}
5064
khenaidoo42dcdfd2021-10-19 17:34:12 -04005065func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04005066 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5067 if err != nil || pgClient == nil {
5068 return err
5069 }
5070 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5071 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005072 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005073 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04005074 _, err = pgClient.ProxyOmciRequest(subCtx, request)
5075 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005076 if status.Code(err) == codes.Unavailable {
5077 dh.setOltAvailable(false)
5078 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005079 logger.Errorw(ctx, "omci-failure",
5080 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005081 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005082 }
5083 return err
5084}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005085
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005086func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
5087 // Check if there are additional TCONT instances necessary/available
5088 pDevEntry.MutexPersOnuConfig.Lock()
5089 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5090 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5091 pDevEntry.MutexPersOnuConfig.Unlock()
5092 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5093 logger.Debugw(ctx, "checking available TCONT instances",
5094 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5095 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5096 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5097 log.Fields{"device-id": dh.device.Id})
5098 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305099 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005100 }
5101 } else {
5102 pDevEntry.MutexPersOnuConfig.Unlock()
5103 }
5104 // Check if there are enough PrioQueue instances available
5105 if dh.pOnuTP != nil {
5106 var numberOfUsPrioQueueDbInsts int
5107
5108 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5109 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305110 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005111 numberOfUsPrioQueueDbInsts++
5112 }
5113 }
5114 // Check if there is an upstream PriorityQueue instance available for each Gem port
5115 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5116 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5117 log.Fields{"device-id": dh.DeviceID,
5118 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5119 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5120 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5121
5122 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5123 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5124 log.Fields{"device-id": dh.device.Id})
5125 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305126 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 +00005127 }
5128 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5129 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5130 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5131 } else {
5132 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5133 log.Fields{"device-id": dh.DeviceID})
5134 }
5135 return nil
5136}
5137
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005138// GetDeviceID - TODO: add comment
5139func (dh *deviceHandler) GetDeviceID() string {
5140 return dh.DeviceID
5141}
5142
5143// GetProxyAddressID - TODO: add comment
5144func (dh *deviceHandler) GetProxyAddressID() string {
5145 return dh.device.ProxyAddress.GetDeviceId()
5146}
5147
5148// GetProxyAddressType - TODO: add comment
5149func (dh *deviceHandler) GetProxyAddressType() string {
5150 return dh.device.ProxyAddress.GetDeviceType()
5151}
5152
5153// GetProxyAddress - TODO: add comment
5154func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5155 return dh.device.ProxyAddress
5156}
5157
5158// GetEventProxy - TODO: add comment
5159func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5160 return dh.EventProxy
5161}
5162
5163// GetOmciTimeout - TODO: add comment
5164func (dh *deviceHandler) GetOmciTimeout() int {
5165 return dh.pOpenOnuAc.omciTimeout
5166}
5167
5168// GetAlarmAuditInterval - TODO: add comment
5169func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5170 return dh.pOpenOnuAc.alarmAuditInterval
5171}
5172
5173// GetDlToOnuTimeout4M - TODO: add comment
5174func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5175 return dh.pOpenOnuAc.dlToOnuTimeout4M
5176}
5177
5178// GetUniEntityMap - TODO: add comment
5179func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5180 return &dh.uniEntityMap
5181}
5182
5183// GetPonPortNumber - TODO: add comment
5184func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5185 return &dh.ponPortNumber
5186}
5187
5188// GetUniVlanConfigFsm - TODO: add comment
5189func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005190 dh.lockVlanConfig.RLock()
5191 value := dh.UniVlanConfigFsmMap[uniID]
5192 dh.lockVlanConfig.RUnlock()
5193 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005194}
5195
5196// GetOnuAlarmManager - TODO: add comment
5197func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5198 return dh.pAlarmMgr
5199}
5200
5201// GetOnuMetricsManager - TODO: add comment
5202func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5203 return dh.pOnuMetricsMgr
5204}
5205
5206// GetOnuTP - TODO: add comment
5207func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5208 return dh.pOnuTP
5209}
5210
5211// GetBackendPathPrefix - TODO: add comment
5212func (dh *deviceHandler) GetBackendPathPrefix() string {
5213 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5214}
5215
5216// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305217func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005218 return dh.pOnuIndication
5219}
5220
5221// RLockMutexDeletionInProgressFlag - TODO: add comment
5222func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5223 dh.mutexDeletionInProgressFlag.RLock()
5224}
5225
5226// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5227func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5228 dh.mutexDeletionInProgressFlag.RUnlock()
5229}
5230
5231// GetDeletionInProgress - TODO: add comment
5232func (dh *deviceHandler) GetDeletionInProgress() bool {
5233 return dh.deletionInProgress
5234}
5235
5236// GetPmConfigs - TODO: add comment
5237func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5238 return dh.pmConfigs
5239}
5240
5241// GetDeviceType - TODO: add comment
5242func (dh *deviceHandler) GetDeviceType() string {
5243 return dh.DeviceType
5244}
5245
5246// GetLogicalDeviceID - TODO: add comment
5247func (dh *deviceHandler) GetLogicalDeviceID() string {
5248 return dh.logicalDeviceID
5249}
5250
5251// GetDevice - TODO: add comment
5252func (dh *deviceHandler) GetDevice() *voltha.Device {
5253 return dh.device
5254}
5255
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005256func (dh *deviceHandler) setOltAvailable(value bool) {
5257 dh.mutexOltAvailable.Lock()
5258 dh.oltAvailable = value
5259 dh.mutexOltAvailable.Unlock()
5260}
5261
5262// IsOltAvailable - TODO: add comment
5263func (dh *deviceHandler) IsOltAvailable() bool {
5264 dh.mutexOltAvailable.RLock()
5265 defer dh.mutexOltAvailable.RUnlock()
5266 return dh.oltAvailable
5267}
5268
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005269// GetMetricsEnabled - TODO: add comment
5270func (dh *deviceHandler) GetMetricsEnabled() bool {
5271 return dh.pOpenOnuAc.MetricsEnabled
5272}
5273
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005274// GetExtendedOmciSupportEnabled - TODO: add comment
5275func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5276 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5277}
5278
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305279// GetExtendedOmciSupportEnabled - TODO: add comment
5280func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5281 return dh.pOpenOnuAc.skipOnuConfig
5282}
5283
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305284func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5285 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5286}
5287
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005288// InitPmConfigs - TODO: add comment
5289func (dh *deviceHandler) InitPmConfigs() {
5290 dh.pmConfigs = &voltha.PmConfigs{}
5291}
5292
5293// GetUniPortMask - TODO: add comment
5294func (dh *deviceHandler) GetUniPortMask() int {
5295 return dh.pOpenOnuAc.config.UniPortMask
5296}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005297
5298func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5299 tpPathFound := false
5300 for _, tpPath := range aTpPathMap {
5301 if tpPath != "" {
5302 tpPathFound = true
5303 }
5304 }
5305 return tpPathFound
5306}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005307
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305308func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5309 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5310 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5311 return resp
5312}
5313
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305314// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5315func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5316 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305317 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5318 return resp
5319}
5320
5321// getOnuFECStats - Get the GEM PM history data of the request ONT device
5322func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5323 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5324 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 +05305325 return resp
5326}
5327
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305328func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5329 return dh.deviceDeleteCommChan
5330}
5331
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005332// PrepareForGarbageCollection - remove references to prepare for garbage collection
5333func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5334 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5335
5336 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5337 // first let the objects rest for some time to give all asynchronously started
5338 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005339 time.Sleep(2 * time.Second)
5340
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005341 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005342
5343 if dh.pOnuTP != nil {
5344 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5345 }
5346 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005347 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5348 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005349 select {
5350 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5351 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5352 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5353 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005354 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005355 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005356 }
5357 if dh.pAlarmMgr != nil {
5358 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5359 }
5360 if dh.pSelfTestHdlr != nil {
5361 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5362 }
5363 if dh.pLockStateFsm != nil {
5364 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5365 }
5366 if dh.pUnlockStateFsm != nil {
5367 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5368 }
5369 if dh.pOnuUpradeFsm != nil {
5370 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5371 }
5372 if dh.pOnuOmciDevice != nil {
5373 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5374 }
5375 for k, v := range dh.UniVlanConfigFsmMap {
5376 v.PrepareForGarbageCollection(ctx, aDeviceID)
5377 delete(dh.UniVlanConfigFsmMap, k)
5378 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305379 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005380 dh.pOnuOmciDevice = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305381 dh.lockDevice.Lock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005382 dh.pOnuTP = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305383 dh.lockDevice.Unlock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005384 dh.pOnuMetricsMgr = nil
5385 dh.pAlarmMgr = nil
5386 dh.pSelfTestHdlr = nil
5387 dh.pLockStateFsm = nil
5388 dh.pUnlockStateFsm = nil
5389 dh.pOnuUpradeFsm = nil
5390}