blob: e6502e9bf84511cbe3bc3b2b7d3d1b252f1a7deb [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/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000031 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040032 "github.com/opencord/voltha-lib-go/v7/pkg/db"
33 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
34 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
35 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
36 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070037 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
39 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
40 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
41 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
42 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
43 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
44 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
45 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053046 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040047 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo42dcdfd2021-10-19 17:34:12 -040049 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040050 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
51 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000052 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000054 "google.golang.org/grpc/codes"
55 "google.golang.org/grpc/status"
bseeniva71b1b662026-02-12 19:07:50 +053056 "google.golang.org/protobuf/proto"
57 "google.golang.org/protobuf/types/known/emptypb"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000058)
59
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060const (
mpagenko101ac942021-11-16 15:01:29 +000061 //constants for reconcile flow check channel
62 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
63 cWaitReconcileFlowAbortOnError = 0xFFFE
64 cWaitReconcileFlowNoActivity = 0xFFFF
65)
66
67const (
68 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000069 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000071
mpagenko1cc3cb42020-07-27 15:24:38 +000072const (
mpagenko44bd8362021-11-15 11:40:05 +000073 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
74 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
75 // as long as such is not available by the libraries - use this workaround
76 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
77)
78
79const (
mpagenko1cc3cb42020-07-27 15:24:38 +000080 // events of Device FSM
bseeniva0c06c862026-02-03 14:04:35 +053081 devEvDeviceInit = "devEvDeviceInit"
82 devEvDeviceUpInd = "devEvDeviceUpInd"
83 devEvDeviceDownInd = "devEvDeviceDownInd"
mpagenko1cc3cb42020-07-27 15:24:38 +000084)
85const (
86 // states of Device FSM
bseeniva0c06c862026-02-03 14:04:35 +053087 devStNull = "devStNull"
88 devStDown = "devStDown"
89 devStInit = "devStInit"
90 devStUp = "devStUp"
mpagenko1cc3cb42020-07-27 15:24:38 +000091)
92
praneeth nalmas5a0a5502022-12-23 15:57:00 +053093// 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 +000094const (
Himani Chawla4d908332020-08-31 12:30:20 +053095 pon = voltha.EventSubCategory_PON
96 //olt = voltha.EventSubCategory_OLT
97 //ont = voltha.EventSubCategory_ONT
98 //onu = voltha.EventSubCategory_ONU
99 //nni = voltha.EventSubCategory_NNI
100 //service = voltha.EventCategory_SERVICE
101 //security = voltha.EventCategory_SECURITY
102 equipment = voltha.EventCategory_EQUIPMENT
103 //processing = voltha.EventCategory_PROCESSING
104 //environment = voltha.EventCategory_ENVIRONMENT
105 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000106)
107
108const (
109 cEventObjectType = "ONU"
110)
111const (
112 cOnuActivatedEvent = "ONU_ACTIVATED"
113)
114
mpagenkof1fc3862021-02-16 10:09:52 +0000115type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000116 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000117 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000118}
119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000120var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
121 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
122 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
123 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
124 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
125 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
126 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
127 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
128 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000129}
130
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000131const (
132 cNoReconciling = iota
133 cOnuConfigReconciling
134 cSkipOnuConfigReconciling
135)
136
Girish Gowdrae95687a2021-09-08 16:30:58 -0700137// FlowCb is the flow control block containing flow add/delete information along with a response channel
138type FlowCb struct {
139 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700140 flowItem *of.OfpFlowStats
141 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400142 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700143 respChan *chan error // channel to report the Flow handling error
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530144 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145}
146
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530147// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530148type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530149 EventProxy eventif.EventProxy
150
151 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000152
khenaidoo7d3c5582021-08-11 18:09:44 -0400153 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000154
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800155 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400156 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800157
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000158 pOpenOnuAc *OpenONUAC
159 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530160 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530161 deviceEntrySet chan bool //channel for DeviceEntry set event
162 pOnuOmciDevice *mib.OnuDeviceEntry
163 pOnuTP *avcfg.OnuUniTechProf
164 pOnuMetricsMgr *pmmgr.OnuMetricsManager
165 pAlarmMgr *almgr.OnuAlarmManager
166 pSelfTestHdlr *otst.SelfTestControlBlock
167 exitChannel chan int
168 pOnuIndication *oop.OnuIndication
169 pLockStateFsm *uniprt.LockStateFsm
170 pUnlockStateFsm *uniprt.LockStateFsm
171
172 stopCollector chan bool
173 stopAlarmManager chan bool
174 stopHeartbeatCheck chan bool
175 uniEntityMap cmn.OnuUniPortMap
176 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
177 pOnuUpradeFsm *swupg.OnuUpgradeFsm
178 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530179 chUniVlanConfigOnRebootDone chan uint16
bseeniva33968f02026-01-30 18:49:48 +0530180 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
181 chReconcilingStopped chan struct{} //channel to indicate the current reconciling has been stopped
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530182 pLastUpgradeImageState *voltha.ImageState
183 upgradeFsmChan chan struct{}
184
185 deviceDeleteCommChan chan bool
186 DeviceID string
187 DeviceType string
188 adminState string
189 logicalDeviceID string
190 ProxyAddressID string
191 ProxyAddressType string
192 parentID string
193
194 flowCbChan []chan FlowCb
195 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
196 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
197 reconcileExpiryComplete time.Duration
198 reconcileExpiryVlanConfig time.Duration
199 lockDevice sync.RWMutex
200 mutexDeviceReason sync.RWMutex
201 mutexCollectorFlag sync.RWMutex
202 mutextAlarmManagerFlag sync.RWMutex
203 lockVlanConfig sync.RWMutex
204 lockVlanAdd sync.RWMutex
205 lockUpgradeFsm sync.RWMutex
206 mutexReconcilingFlag sync.RWMutex
207 mutexReconcilingFirstPassFlag sync.RWMutex
208 mutexReconcilingReasonUpdate sync.RWMutex
209 mutexReadyForOmciConfig sync.RWMutex
210 mutexDeletionInProgressFlag sync.RWMutex
211 mutexFlowMonitoringRoutineFlag sync.RWMutex
212 mutexForDisableDeviceRequested sync.RWMutex
213 mutexOltAvailable sync.RWMutex
214 mutexKvStoreContext sync.Mutex
215 ponPortNumber uint32
216
217 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000218
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219 //flowMgr *OpenOltFlowMgr
220 //eventMgr *OpenOltEventMgr
221 //resourceMgr *rsrcMgr.OpenOltResourceMgr
222
223 //discOnus sync.Map
224 //onus sync.Map
225 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530226 collectorIsRunning bool
227 alarmManagerIsRunning bool
228 upgradeCanceled bool
229 reconciling uint8
230 reconcilingFirstPass bool
231 reconcilingReasonUpdate bool
232 readyForOmciConfig bool
233 deletionInProgress bool
234 disableDeviceRequested bool // this flag identify ONU received disable request or not
235 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236}
237
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530238// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400239func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400241 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400243 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000245 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.DeviceType = cloned.Type
247 dh.adminState = "up"
248 dh.device = cloned
249 dh.pOpenOnuAc = adapter
250 dh.exitChannel = make(chan int, 1)
251 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000252 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000253 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000254 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530255 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530256 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 dh.stopHeartbeatCheck = make(chan bool, 2)
258 //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 +0000259 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000260 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000261 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000262 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000263 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300264 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000265 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000266 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000267 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000268 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300269 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000270 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000271 dh.chReconcilingFinished = make(chan bool)
bseeniva33968f02026-01-30 18:49:48 +0530272 dh.chReconcilingStopped = make(chan struct{})
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},
bseeniva0c06c862026-02-03 14:04:35 +0530302 {Name: devEvDeviceUpInd, Src: []string{devStInit, devStDown}, Dst: devStUp},
mpagenko1cc3cb42020-07-27 15:24:38 +0000303 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 },
305 fsm.Callbacks{
bseeniva0c06c862026-02-03 14:04:35 +0530306 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
307 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
308 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
309 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
310 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 },
312 )
mpagenkoaf801632020-07-03 10:00:42 +0000313
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314 return &dh
315}
316
Himani Chawla6d2ae152020-09-02 13:11:20 +0530317// start save the device to the data model
318func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000319 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000321 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322}
323
Himani Chawla4d908332020-08-31 12:30:20 +0530324/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530326func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 logger.Debug("stopping-device-handler")
328 dh.exitChannel <- 1
329}
Himani Chawla4d908332020-08-31 12:30:20 +0530330*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331
332// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530333// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530335// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530336func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400337 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000339 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530340
mpagenko1cc3cb42020-07-27 15:24:38 +0000341 if dh.pDeviceStateFsm.Is(devStNull) {
342 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000343 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 +0000344 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000345 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800346 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
347 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800348 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400349 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800351 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800352 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000355 }
356
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000357}
358
khenaidoo42dcdfd2021-10-19 17:34:12 -0400359func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000360 /* 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 +0530361 //assuming omci message content is hex coded!
362 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000365 */
bseenivacfcd8f72026-01-30 21:06:49 +0530366 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000368 if pDevEntry.PDevOmciCC != nil {
bseenivacfcd8f72026-01-30 21:06:49 +0530369 logger.Debugw(ctx, "pDevEntry.PDevOmciCC is not nil", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000370 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000371 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000372 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
373 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
376 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530377}
378
khenaidoo42dcdfd2021-10-19 17:34:12 -0400379func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000380 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000381
bseenivacfcd8f72026-01-30 21:06:49 +0530382 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000383 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
385 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000386 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530387 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530388 if dh.pOnuTP == nil {
389 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000390 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530392 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000393 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 if !dh.IsReadyForOmciConfig() {
396 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
397 "device-state": dh.GetDeviceReasonString()})
bseeniva0cbc62a2026-01-23 19:08:36 +0530398 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000401 //previous state test here was just this one, now extended for more states to reject the SetRequest:
402 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
403 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530404
Himani Chawla26e555c2020-08-31 12:30:20 +0530405 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
407 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000408 dh.pOnuTP.LockTpProcMutex()
409 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530410 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411
mpagenko44bd8362021-11-15 11:40:05 +0000412 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530413 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
414 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 }
416 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000417 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800418 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000419 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
420 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 return err
422 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000423 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
424 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000426 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530427
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400429 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000430 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
431 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000432
bseeniva71b1b662026-02-12 19:07:50 +0530433 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, tpInst.TpInstance)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000434 if err != nil {
435 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
436 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
437 // stopping all further processing
438 _ = dh.UpdateInterface(ctx)
439 return err
440 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 // if there has been some change for some uni TechProfilePath
442 //in order to allow concurrent calls to other dh instances we do not wait for execution here
443 //but doing so we can not indicate problems to the caller (who does what with that then?)
444 //by now we just assume straightforward successful execution
445 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
446 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530447
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 // deadline context to ensure completion of background routines waited for
449 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
450 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
451 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000453 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700454
455 var wg sync.WaitGroup
456 wg.Add(1) // for the 1 go routine to finish
457 // attention: deadline completion check and wg.Done is to be done in both routines
bseeniva71b1b662026-02-12 19:07:50 +0530458 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700459 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
461 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 -0700462 return tpErr
463 }
464 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
465 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530466 defer cancel2()
467 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
468 if err1 != nil {
469 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
470 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700471 }
472 return nil
473 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000474 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700475 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700476 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000479 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
480 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 return nil
482}
483
khenaidoo42dcdfd2021-10-19 17:34:12 -0400484func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000485 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530486
bseeniva0cbc62a2026-01-23 19:08:36 +0530487 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 if dh.pOnuTP == nil {
489 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530492 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 dh.pOnuTP.LockTpProcMutex()
497 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530498 defer dh.lockDevice.RUnlock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530499
mpagenko0f543222021-11-03 16:24:14 +0000500 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
501 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
502 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530503 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
504 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000505 }
506 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000509 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
510 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800511 return err
512 }
mpagenko0f543222021-11-03 16:24:14 +0000513 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
514 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000515 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
Mahir Gunyel9545be22021-07-04 15:53:16 -0700517 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
Himani Chawla26e555c2020-08-31 12:30:20 +0530520}
521
khenaidoo42dcdfd2021-10-19 17:34:12 -0400522func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000523 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 +0000524
bseenivacfcd8f72026-01-30 21:06:49 +0530525 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
528 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000529 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530530 dh.lockDevice.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 if dh.pOnuTP == nil {
532 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 log.Fields{"device-id": dh.DeviceID})
bseeniva0cbc62a2026-01-23 19:08:36 +0530535 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000536 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530537 }
538
Himani Chawla26e555c2020-08-31 12:30:20 +0530539 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 dh.pOnuTP.LockTpProcMutex()
541 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530542 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000543
mpagenko0f543222021-11-03 16:24:14 +0000544 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
545 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
546 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530547 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
548 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000549 }
550 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700551 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800553 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000554 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
555 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800556 return err
557 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530559
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000560 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
561 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530562 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000563 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 +0530564 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
565 if err1 != nil {
566 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
567 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000568 }
569
Mahir Gunyel9545be22021-07-04 15:53:16 -0700570 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000572
Mahir Gunyel9545be22021-07-04 15:53:16 -0700573}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000574
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
bseenivacfcd8f72026-01-30 21:06:49 +0530577 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
580 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530581 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700582 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700584 resourceName = "Gem"
585 } else {
586 resourceName = "Tcont"
587 }
588
589 // deadline context to ensure completion of background routines waited for
590 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
591 dctx, cancel := context.WithDeadline(context.Background(), deadline)
592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700594
595 var wg sync.WaitGroup
596 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700598 resource, entryID, &wg)
599 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000600 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
601 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 return err
603 }
604
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
606 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
607 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
608 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700609 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530610 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700611 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000612 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 +0530613 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
614 if err != nil {
615 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700616 return err
617 }
618 }
619 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000620 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700621 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530622 return nil
623}
624
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530625// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400627 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400628 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700629 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
630 var errorsList []error
631 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530632 if dh.GetPersRebootFlag(ctx) {
bseenivabc19dec2026-02-04 11:56:23 +0530633 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 +0530634 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
635 }
mpagenko01e726e2020-10-23 09:45:29 +0000636 //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 +0000637 if apOfFlowChanges.ToRemove != nil {
638 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000639 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 "device-id": dh.DeviceID})
642 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700643 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000644 continue
645 }
646 flowInPort := flow.GetInPort(flowItem)
647 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
649 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700650 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000651 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000653 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000654 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000657 continue
658 } else {
659 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000660 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000661 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
662 loUniPort = uniPort
663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000664 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000666 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700668 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000669 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000670 }
671 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000673 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
674 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700675
676 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
677 // Step1 : Fill flowControlBlock
678 // Step2 : Push the flowControlBlock to ONU channel
679 // Step3 : Wait on response channel for response
680 // Step4 : Return error value
681 startTime := time.Now()
682 respChan := make(chan error)
683 flowCb := FlowCb{
684 ctx: ctx,
685 addFlow: false,
686 flowItem: flowItem,
687 flowMetaData: nil,
688 uniPort: loUniPort,
689 respChan: &respChan,
690 }
691 dh.flowCbChan[loUniPort.UniID] <- flowCb
692 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
693 // Wait on the channel for flow handlers return value
694 retError = <-respChan
695 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
696 if retError != nil {
697 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
698 log.Fields{"device-id": dh.DeviceID, "error": retError})
699 errorsList = append(errorsList, retError)
700 continue
701 }
702 } else {
703 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
704 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000705 }
706 }
707 }
708 }
mpagenko01e726e2020-10-23 09:45:29 +0000709 if apOfFlowChanges.ToAdd != nil {
710 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
711 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000713 "device-id": dh.DeviceID})
714 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700715 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000716 continue
717 }
718 flowInPort := flow.GetInPort(flowItem)
719 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
721 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700722 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000723 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000725 } else if flowInPort == dh.ponPortNumber {
726 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000729 continue
730 } else {
731 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000732 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000733 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
734 loUniPort = uniPort
735 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000736 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000738 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000739 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700740 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000741 continue
mpagenko01e726e2020-10-23 09:45:29 +0000742 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000743 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
744 // if not, we just throw some error here to have an indication about that, if we really need to support that
745 // then we would need to create some means to activate the internal stored flows
746 // after the device gets active automatically (and still with its dependency to the TechProfile)
747 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
748 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000749 if !dh.IsReadyForOmciConfig() {
750 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
751 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700752 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
753 errorsList = append(errorsList, retError)
754 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000755 }
756
mpagenko01e726e2020-10-23 09:45:29 +0000757 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000759 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
760 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700761 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
762 // Step1 : Fill flowControlBlock
763 // Step2 : Push the flowControlBlock to ONU channel
764 // Step3 : Wait on response channel for response
765 // Step4 : Return error value
766 startTime := time.Now()
767 respChan := make(chan error)
768 flowCb := FlowCb{
769 ctx: ctx,
770 addFlow: true,
771 flowItem: flowItem,
772 flowMetaData: apFlowMetaData,
773 uniPort: loUniPort,
774 respChan: &respChan,
775 }
776 dh.flowCbChan[loUniPort.UniID] <- flowCb
777 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
778 // Wait on the channel for flow handlers return value
779 retError = <-respChan
780 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
781 if retError != nil {
782 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
783 log.Fields{"device-id": dh.DeviceID, "error": retError})
784 errorsList = append(errorsList, retError)
785 continue
786 }
787 } else {
788 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
789 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000790 }
791 }
792 }
793 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700794 if len(errorsList) > 0 {
795 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
796 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
797 }
798 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000799}
800
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530801// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
802// following are the expected device states after this activity:
803// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000804// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
806 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300807 dh.mutexForDisableDeviceRequested.Lock()
808 dh.disableDeviceRequested = true
809 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000810 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000811 //note that disableDevice sequences in some 'ONU active' state may yield also
812 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000813 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000815 //disable-device shall be just a UNi/ONU-G related admin state setting
816 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000817
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000819 // disable UNI ports/ONU
820 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
821 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000823 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000826 }
827 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000828 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000830 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400831 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000832 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000833 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400834 OperStatus: voltha.OperStatus_UNKNOWN,
835 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000836 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000838 }
mpagenko01e726e2020-10-23 09:45:29 +0000839 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000840
841 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000842 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000843 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300844 }
845}
846
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530847// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
849 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000850
mpagenkoaa3afe92021-05-21 16:20:58 +0000851 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000852 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
853 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
854 // for real ONU's that should have nearly no influence
855 // Note that for real ONU's there is anyway a problematic situation with following sequence:
856 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
857 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
858 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000860
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000861 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000862 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300863 dh.mutexForDisableDeviceRequested.Lock()
864 dh.disableDeviceRequested = false
865 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000866 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000868 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000870 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000871 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300872}
873
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530875 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000876
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000880 return
881 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000882 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000883 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000885 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000887 }
mpagenko101ac942021-11-16 15:01:29 +0000888 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000889 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000890 }
Himani Chawla4d908332020-08-31 12:30:20 +0530891 var onuIndication oop.OnuIndication
akashreddykb03dde02025-12-02 10:53:18 +0530892 var rebootInProgress bool
893 var persUniUnlockDone bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 pDevEntry.MutexPersOnuConfig.RLock()
895 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
896 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
897 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
898 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
akashreddykb03dde02025-12-02 10:53:18 +0530899 rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
900 persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 pDevEntry.MutexPersOnuConfig.RUnlock()
akashreddykb03dde02025-12-02 10:53:18 +0530902 if rebootInProgress {
903 if persUniUnlockDone {
904 logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
905 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
906 return
907 }
908 }
909 if onuIndication.OperState == "up" {
bseeniva0c06c862026-02-03 14:04:35 +0530910 if !dh.pDeviceStateFsm.Can(devEvDeviceUpInd) {
911 logger.Errorw(ctx, "invalid state transition for event device up indication", log.Fields{"currentState": dh.pDeviceStateFsm.Current()})
912 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
913 return
914 }
915 err := dh.pDeviceStateFsm.Event(devEvDeviceUpInd, &onuIndication)
916 if err != nil {
akashreddykb03dde02025-12-02 10:53:18 +0530917 logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
918 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
919 return
920 }
921 } else {
922 logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
923 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
924 return
925 }
926 logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000927}
928
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000929func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530930 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000931
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000932 continueWithFlowConfig := false
933
bseenivacfcd8f72026-01-30 21:06:49 +0530934 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000935 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000937 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
938 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000939 }
bseeniva0cbc62a2026-01-23 19:08:36 +0530940 dh.lockDevice.RLock()
941 if dh.pOnuTP == nil {
942 //should normally not happen ...
943 logger.Warnw(ctx, "onuTechProf instance not set up for reconcile tech prof - ignoring request",
944 log.Fields{"device-id": dh.DeviceID})
945 dh.lockDevice.RUnlock()
946 return continueWithFlowConfig
947 }
948
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000949 dh.pOnuTP.LockTpProcMutex()
950 defer dh.pOnuTP.UnlockTpProcMutex()
bseeniva0cbc62a2026-01-23 19:08:36 +0530951 defer dh.lockDevice.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000954 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
956 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530957 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000959 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
960 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000961 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000962 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700963 techProfsFound := false
964 techProfInstLoadFailed := false
965outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000967 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000968 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000969 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000970 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000971 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000972 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000973 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000974 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
975 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000976 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000978 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700979 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800980 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000981 pDevEntry.MutexReconciledTpInstances.RLock()
bseeniva71b1b662026-02-12 19:07:50 +0530982 if _, ok := pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000983 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000984 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000985 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700986 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000987 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700988 break outerLoop
989 }
bseeniva71b1b662026-02-12 19:07:50 +0530990 // Access the TpInstance directly without copying the whole message
991 techTpInst := pDevEntry.ReconciledTpInstances[uniID][tpID].TechTpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000992 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000993 continueWithFlowConfig = true // valid TP found - try flow configuration later
bseeniva71b1b662026-02-12 19:07:50 +0530994 var tpInst *tech_profile.TechProfileInstance
995 switch tpInstCase := techTpInst.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400996 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
bseeniva71b1b662026-02-12 19:07:50 +0530997 tpInst = tpInstCase.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000998 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001000 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001001 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001003 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1004 break outerLoop
1005 }
1006
Girish Gowdra041dcb32020-11-16 16:54:30 -08001007 // deadline context to ensure completion of background routines waited for
1008 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
1009 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001010 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001011
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001013 var wg sync.WaitGroup
1014 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
1018 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001019 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
1020 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -08001021 }
mpagenko2dc896e2021-08-02 12:03:59 +00001022 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023 if len(uniData.PersFlowParams) != 0 {
1024 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001025 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +00001027 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 } // for all UNI entries from SOnuPersistentData
1029 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
1030 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001031 }
mpagenko2dc896e2021-08-02 12:03:59 +00001032
1033 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1034 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001035
1036 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +00001037}
1038
1039func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1040 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1041 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301042 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001044 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001045 return
1046 }
mpagenko2dc896e2021-08-02 12:03:59 +00001047 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001048 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001049 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001050 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001052 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001053 }
mpagenko2dc896e2021-08-02 12:03:59 +00001054 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301055 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001056 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001057 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001058 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001059}
1060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001061func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1062 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063
bseenivacfcd8f72026-01-30 21:06:49 +05301064 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001065 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001066 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001067 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001068 return
1069 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001070
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001071 pDevEntry.MutexPersOnuConfig.RLock()
1072 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1073 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301074 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001075 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001076 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001077 return
1078 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001079 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001080 var uniVlanConfigEntries []uint8
1081 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1082
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001083 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001084 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1085 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001086 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001087 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001088 continue
1089 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001090 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001091 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001092 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001093 // It doesn't make sense to configure any flows if no TPs are available
1094 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001096 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1097 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001098 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001099 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001100
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001101 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001102 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001103 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001104 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001105 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1106 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001107 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001108 return
1109 }
mpagenko101ac942021-11-16 15:01:29 +00001110 //needed to split up function due to sca complexity
1111 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1112
mpagenko2dc896e2021-08-02 12:03:59 +00001113 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001114 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001115 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1116 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001117 // this can't be used as global finished reconciling flag because
1118 // assumes is getting called before the state machines for the last flow is completed,
1119 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1121 } // for all UNI entries from SOnuPersistentData
1122 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001123
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001124 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301125 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001127 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001128 return
1129 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001130 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1131 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1132 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1133 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1134 log.Fields{"device-id": dh.DeviceID})
1135 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1136 if pDevEntry != nil {
1137 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001138 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001139 } else {
1140 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1141 log.Fields{"device-id": dh.DeviceID})
1142 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1143 if pDevEntry != nil {
1144 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1145 }
1146 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001147 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001148 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001149}
1150
mpagenko101ac942021-11-16 15:01:29 +00001151func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1152 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1153 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1154 flowsProcessed := 0
1155 lastFlowToReconcile := false
1156 loUniID := apUniPort.UniID
1157 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001158 if !(*apFlowsFound) {
1159 *apFlowsFound = true
1160 syncChannel := make(chan struct{})
1161 // start go routine with select() on reconciling vlan config channel before
1162 // starting vlan config reconciling process to prevent loss of any signal
1163 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1164 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1165 //block until the wait routine is really blocked on channel input
1166 // in order to prevent to early ready signal from VlanConfig processing
1167 <-syncChannel
1168 }
1169 if flowsProcessed == len(aPersFlowParam)-1 {
1170 var uniAdded bool
1171 lastFlowToReconcile = true
1172 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1173 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001174 }
1175 }
mpagenko101ac942021-11-16 15:01:29 +00001176 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1177 "device-id": dh.DeviceID, "uni-id": loUniID,
1178 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1179 dh.lockVlanConfig.Lock()
1180 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1181 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1182 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301183 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 +00001184 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1185 }
1186 } else {
1187 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301188 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301189 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001190 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1191 }
1192 }
1193 dh.lockVlanConfig.Unlock()
1194 flowsProcessed++
1195 } //for all flows of this UNI
1196}
1197
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301198// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1199//
1200// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001201func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1202 waitGroup *cmn.WaitGroupWithTimeOut) {
1203 var reconciledUniVlanConfigEntries []uint8
1204 var appended bool
1205 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1206 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1207 "device-id": dh.DeviceID, "expiry": expiry})
1208 // indicate blocking on channel now to the caller
1209 aSyncChannel <- struct{}{}
1210 for {
1211 select {
1212 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1213 switch uniIndication {
1214 // no activity requested (should normally not be received) - just continue waiting
1215 case cWaitReconcileFlowNoActivity:
1216 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1217 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301218 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001219 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1220 return
1221 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1222 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301223 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001224 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1225 return
1226 // this should be a valid UNI vlan config done indication
1227 default:
1228 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301229 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001230 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1231 if reconciledUniVlanConfigEntries, appended =
1232 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1233 waitGroup.Done()
1234 }
1235 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301236 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 +00001237 }
1238 } //switch uniIndication
1239
1240 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1241 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1242 log.Fields{"device-id": dh.DeviceID})
1243 return
1244 }
1245 }
1246}
1247
1248func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1249 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1250}
1251
1252func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1253 for _, ele := range slice {
1254 if ele == val {
1255 return slice, false
1256 }
1257 }
1258 return append(slice, val), true
1259}
1260
1261// sendChReconcileFinished - sends true or false on reconcileFinish channel
1262func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1263 if dh != nil { //if the object still exists (might have been already deleted in background)
1264 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1265 select {
1266 case dh.chReconcilingFinished <- success:
1267 default:
1268 }
bseeniva33968f02026-01-30 18:49:48 +05301269 // Wait until the current running reconciliation has stopped
1270 <-dh.chReconcilingStopped
mpagenko101ac942021-11-16 15:01:29 +00001271 }
1272}
1273
1274// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1275func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1276 if dh != nil { //if the object still exists (might have been already deleted in background)
1277 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1278 select {
1279 case dh.chUniVlanConfigReconcilingDone <- value:
1280 default:
1281 }
1282 }
1283}
1284
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301285func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1286 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1287
1288 defer dh.UpdateAndStoreRebootState(ctx, false)
1289 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1290 if pDevEntry == nil {
1291 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1292 return
1293 }
1294
1295 pDevEntry.MutexPersOnuConfig.RLock()
1296 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1297 pDevEntry.MutexPersOnuConfig.RUnlock()
1298 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1299 log.Fields{"device-id": dh.DeviceID})
1300 return
1301 }
1302 flowsFound := false
1303 var uniVlanConfigEntries []uint8
1304 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1305
1306 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1307 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1308 if len(uniData.PersFlowParams) == 0 {
1309 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1310 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1311 continue
1312 }
1313 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1314 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1315 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1316 // It doesn't make sense to configure any flows if no TPs are available
1317 continue
1318 }
1319 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1320 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1321 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1322 pDevEntry.MutexPersOnuConfig.RUnlock()
1323
1324 var uniPort *cmn.OnuUniPort
1325 var exist bool
1326 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1327 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1328 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1329 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1330 return
1331 }
1332
1333 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1334
1335 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1336 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1337 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1338 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1339 // this can't be used as global finished reconciling flag because
1340 // assumes is getting called before the state machines for the last flow is completed,
1341 // while this is not guaranteed.
1342 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1343 } // for all UNI entries from SOnuPersistentData
1344 pDevEntry.MutexPersOnuConfig.RUnlock()
1345
1346 if !flowsFound {
1347 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1348 log.Fields{"device-id": dh.DeviceID})
1349 return
1350 }
1351 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1352 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1353 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1354 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1355 log.Fields{"device-id": dh.DeviceID})
1356 } else {
1357 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1358 log.Fields{"device-id": dh.DeviceID})
1359 return
1360 }
1361}
1362
1363func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1364 dh.UpdateRebootPersData(ctx, flag)
1365 if err := dh.StorePersistentData(ctx); err != nil {
1366 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1367 }
1368}
1369
1370func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1371 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1372 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1373 flowsProcessed := 0
1374 lastFlowToConfigOnReboot := false
1375 loUniID := apUniPort.UniID
1376 for _, flowData := range aPersFlowParam {
1377 if !(*apFlowsFound) {
1378 *apFlowsFound = true
1379 syncChannel := make(chan struct{})
1380 // start go routine with select() on reconciling vlan config channel before
1381 // starting vlan config reconciling process to prevent loss of any signal
1382 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1383 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1384 //block until the wait routine is really blocked on channel input
1385 // in order to prevent to early ready signal from VlanConfig processing
1386 <-syncChannel
1387 }
1388 if flowsProcessed == len(aPersFlowParam)-1 {
1389 var uniAdded bool
1390 lastFlowToConfigOnReboot = true
1391 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1392 apWaitGroup.Add(1) //increment the waiting group
1393 }
1394 }
1395 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1396 "device-id": dh.DeviceID, "uni-id": loUniID,
1397 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1398 dh.lockVlanConfig.Lock()
1399 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1400 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1401 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1402 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 {
1403 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1404 }
1405 } else {
1406 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1407 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1408 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1409 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1410 }
1411 }
1412 dh.lockVlanConfig.Unlock()
1413 flowsProcessed++
1414 } //for all flows of this UNI
1415}
1416
1417func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1418 waitGroup *cmn.WaitGroupWithTimeOut) {
1419 var rebootUniVlanConfigEntries []uint8
1420 var appended bool
1421 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1422 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1423 "device-id": dh.DeviceID, "expiry": expiry})
1424 // indicate blocking on channel now to the caller
1425 aSyncChannel <- struct{}{}
1426 for {
1427 select {
1428 case <-dh.deviceDeleteCommChan:
1429 // Cancel the context and return
1430 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1431 return
1432
1433 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1434 switch uniIndication {
1435 // this should be a valid UNI vlan config done indication
1436 default:
1437 if uniIndication < platform.MaxUnisPerOnu {
1438 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1439 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1440 if rebootUniVlanConfigEntries, appended =
1441 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1442 waitGroup.Done()
1443 }
1444 } else {
1445 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1446 }
1447 } //switch uniIndication
1448
1449 case <-time.After(expiry):
1450 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1451 log.Fields{"device-id": dh.DeviceID})
1452 return
1453 }
1454 }
1455}
1456
1457func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1458 if dh != nil { //if the object still exists (might have been already deleted in background)
1459 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1460 select {
1461 case dh.chUniVlanConfigOnRebootDone <- value:
1462 default:
1463 }
1464 }
1465}
1466
1467func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
bseenivabc19dec2026-02-04 11:56:23 +05301468 logger.Infow(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301469 techProfInstLoadFailed := false
1470 continueWithFlowConfig := false
1471 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1472 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1473 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1474
1475 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1476 if pDevEntry == nil {
1477 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1478 return continueWithFlowConfig
1479 }
1480 dh.lockDevice.RLock()
1481 if dh.pOnuTP == nil {
1482 //should normally not happen ...
1483 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1484 log.Fields{"device-id": dh.DeviceID})
1485 dh.lockDevice.RUnlock()
1486 return continueWithFlowConfig
1487 }
1488
1489 dh.pOnuTP.LockTpProcMutex()
1490 defer dh.pOnuTP.UnlockTpProcMutex()
1491 defer dh.lockDevice.RUnlock()
1492
1493 pDevEntry.MutexPersOnuConfig.RLock()
1494 persMutexLock := true
1495 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1496 pDevEntry.MutexPersOnuConfig.RUnlock()
1497 logger.Info(ctx, "no uni-configs have been stored - aborting",
1498 log.Fields{"device-id": dh.DeviceID})
1499 return continueWithFlowConfig
1500 }
1501
1502outerLoop:
1503 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1504 uniID := uniData.PersUniID
1505
1506 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1507 logger.Debugw(ctx, "no TPs stored for uniID",
1508 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1509 continue
1510 }
1511 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1512 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1513 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1514 pDevEntry.MutexPersOnuConfig.RUnlock()
1515 persMutexLock = false
1516 for tpID, tpPath := range uniData.PersTpPathMap {
1517 if tpPath != "" {
1518 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1519 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1520 })
1521 // Attempt the initial call before entering the retry loop
1522 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1523 if err != nil {
1524 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1525 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1526 })
1527 techProfInstLoadFailed = true
1528 break outerLoop
1529 }
1530 if iaTechTpInst != nil {
bseeniva71b1b662026-02-12 19:07:50 +05301531 var tpInst *tech_profile.TechProfileInstance
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301532 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1533 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
bseeniva71b1b662026-02-12 19:07:50 +05301534 tpInst = techTpInst.TpInstance
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301535 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1536 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1537 default: // do not support epon or other tech
1538 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1539 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1540 techProfInstLoadFailed = true
1541 break outerLoop
1542 }
1543
1544 continueWithFlowConfig = true
1545 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1546 dctx, cancel := context.WithDeadline(ctx, deadline)
1547
1548 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1549 var wg sync.WaitGroup
1550 wg.Add(1) // for the 1 go routine to finish
1551 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1552 // Wait for either completion or cancellation
1553 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1554 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1555 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1556 techProfInstLoadFailed = true
1557 continueWithFlowConfig = false
1558 break outerLoop
1559 }
1560 } else {
1561 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1562 techProfInstLoadFailed = true
1563 break outerLoop
1564 }
1565 } else {
1566 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1567 "uni-id": uniID, "device-id": dh.DeviceID})
1568 techProfInstLoadFailed = true
1569 break outerLoop
1570 }
1571 }
1572 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1573 persMutexLock = true
1574 }
1575 if persMutexLock {
1576 pDevEntry.MutexPersOnuConfig.RUnlock()
1577 }
1578 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1579 return continueWithFlowConfig
1580}
1581
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001583 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001584
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001585 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001586 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001587 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001588 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001589 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001590 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001591
1592 // deadline context to ensure completion of background routines waited for
1593 //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 +05301594 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001595 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301596 defer cancel()
1597 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1598 if err != nil {
1599 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1600 return err
1601 }
1602 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001603}
1604
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301605// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001606// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301607//
1608// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1609//
1610// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301611func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001613 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301615 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001616 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301618 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301620 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301621 }
mpagenko01e726e2020-10-23 09:45:29 +00001622
1623 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001625
mpagenko44bd8362021-11-15 11:40:05 +00001626 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001628 // 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 +05301629 go func() {
1630 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1631 DeviceId: dh.DeviceID,
1632 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1633 OperStatus: voltha.OperStatus_DISCOVERED,
1634 }); err != nil {
1635 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1636 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1637 return
1638 }
bseenivabc19dec2026-02-04 11:56:23 +05301639 if dh.GetDeviceTechProfOnReboot() {
1640 dh.UpdateAndStoreRebootState(ctx, true)
1641 }
akashreddyke30dfa92025-11-26 10:51:57 +05301642 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1643 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1644 return
1645 }
1646 dh.SetReadyForOmciConfig(false)
1647 }()
1648 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001649 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1650 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1651 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1652 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001653}
1654
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301655// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1656//
1657// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001658func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001659 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001660 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001661 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001662
1663 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301664 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00001665 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1667 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001668 }
1669
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001671 var inactiveImageID uint16
1672 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1673 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001674 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1675 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001676 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001678 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001679 if err == nil {
1680 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1681 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001683 }
1684 } else {
1685 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001687 }
mpagenko15ff4a52021-03-02 10:09:20 +00001688 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001689 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001690 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001691 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1692 dh.upgradeCanceled = true
1693 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1694 }
mpagenko38662d02021-08-11 09:45:19 +00001695 //no effort spent anymore for the old API to automatically cancel and restart the download
1696 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001697 }
mpagenko15ff4a52021-03-02 10:09:20 +00001698 } else {
1699 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001700 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001701 }
1702 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001703 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1704 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001705 }
1706 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001707}
1708
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301709// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001710// after the OnuImage has been downloaded to the adapter, called in background
1711func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
bseeniva0b4286b2026-01-30 13:05:42 +05301712 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string, aCancel context.CancelFunc) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001713
1714 var err error
bseenivacfcd8f72026-01-30 21:06:49 +05301715 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001716 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001718 return
1719 }
1720
1721 var inactiveImageID uint16
1722 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1723 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001724 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001725
mpagenko59862f02021-10-11 08:53:18 +00001726 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001727 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001728 // but must be still locked at calling createOnuUpgradeFsm
1729 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1730 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1731 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001732 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1733 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001734 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001735 //flush the remove upgradeFsmChan channel
1736 select {
1737 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001738 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001739 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001740 }
mpagenko59862f02021-10-11 08:53:18 +00001741 dh.lockUpgradeFsm.Unlock()
1742 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1743 dh.upgradeCanceled = true
1744 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1745 }
mpagenko38662d02021-08-11 09:45:19 +00001746 select {
1747 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001749 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1750 return
1751 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001752 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001753 }
mpagenko59862f02021-10-11 08:53:18 +00001754 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001755 }
mpagenko38662d02021-08-11 09:45:19 +00001756
1757 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001758 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001759 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001761 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001762 if err == nil {
1763 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1764 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1765 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001766 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001767 return
1768 }
mpagenko38662d02021-08-11 09:45:19 +00001769 } else {
1770 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001771 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001772 }
bseeniva0b4286b2026-01-30 13:05:42 +05301773 go func() {
1774 onuDlChn := dh.pOnuUpradeFsm.GetOnuDLChannel()
1775 select {
1776 case <-ctx.Done():
1777 logger.Errorw(ctx, "context Deadline Exceeded aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1778 dh.lockUpgradeFsm.Lock()
1779 if dh.pOnuUpradeFsm != nil {
1780 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1781 }
1782 dh.lockUpgradeFsm.Unlock()
1783 return
1784 case <-dh.deviceDeleteCommChan:
1785 logger.Errorw(ctx, "device deleted aborting ONU SW upgrade", log.Fields{"device-id": dh.DeviceID, "err": ctx.Err()})
1786 dh.lockUpgradeFsm.Lock()
1787 if dh.pOnuUpradeFsm != nil {
1788 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST)
1789 }
1790 dh.lockUpgradeFsm.Unlock()
1791 return
1792 case success := <-onuDlChn:
1793 logger.Infow(ctx, "onu SW upgrade download completed", log.Fields{"isSuccess": success, "device-id": dh.DeviceID})
1794 aCancel()
1795 return
1796
1797 }
1798 }()
mpagenkoc26d4c02021-05-06 14:27:57 +00001799 return
1800 }
1801 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001802 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001803}
1804
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301805// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001806func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1807 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001808 var err error
1809 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1810 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1811 // 2.) activation of the inactive image
1812
bseenivacfcd8f72026-01-30 21:06:49 +05301813 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001814 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001815 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1816 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001817 }
1818 dh.lockUpgradeFsm.RLock()
1819 if dh.pOnuUpradeFsm != nil {
1820 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001821 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001822 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001823 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1824 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001825 }
mpagenko59862f02021-10-11 08:53:18 +00001826 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1827 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1828 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1829 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001830 // use the OnuVendor identification from this device for the internal unique name
1831 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001832 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001833 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001834 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001835 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001836 "device-id": dh.DeviceID, "error": err})
1837 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001838 }
mpagenko183647c2021-06-08 15:25:04 +00001839 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001841 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001842 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001843 } //else
1844 dh.lockUpgradeFsm.RUnlock()
1845
1846 // 2.) check if requested image-version equals the inactive one and start its activation
1847 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1848 var inactiveImageID uint16
1849 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1850 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001851 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1852 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001853 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001854 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001855 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001856 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001857 if err == nil {
1858 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1859 inactiveImageID, aCommitRequest); err != nil {
1860 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001861 "device-id": dh.DeviceID, "error": err})
1862 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001863 }
1864 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001865 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001866 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001867 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001868 } //else
1869 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001870 "device-id": dh.DeviceID, "error": err})
1871 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001872}
1873
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301874// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001875func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1876 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001877 var err error
1878 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1879 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1880 // 2.) commitment of the active image
1881
bseenivacfcd8f72026-01-30 21:06:49 +05301882 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkoc26d4c02021-05-06 14:27:57 +00001883 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001884 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1885 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001886 }
1887 dh.lockUpgradeFsm.RLock()
1888 if dh.pOnuUpradeFsm != nil {
1889 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001890 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001891 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001892 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1893 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001894 }
mpagenko59862f02021-10-11 08:53:18 +00001895 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1896 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1897 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1898 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001899 // use the OnuVendor identification from this device for the internal unique name
1900 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001901 // 1.) check a started upgrade process and relay the commitment request to it
1902 // the running upgrade may be based either on the imageIdentifier (started from download)
1903 // or on the imageVersion (started from pure activation)
1904 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1905 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001906 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 "device-id": dh.DeviceID, "error": err})
1908 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001909 }
mpagenko183647c2021-06-08 15:25:04 +00001910 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001911 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001912 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001913 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001914 } //else
1915 dh.lockUpgradeFsm.RUnlock()
1916
mpagenko183647c2021-06-08 15:25:04 +00001917 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001918 var activeImageID uint16
1919 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1920 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001921 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1922 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001923 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001924 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001925 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001926 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001927 if err == nil {
1928 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1929 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 "device-id": dh.DeviceID, "error": err})
1931 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001932 }
1933 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001934 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001935 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001936 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001937 } //else
1938 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 "device-id": dh.DeviceID, "error": err})
1940 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001941}
1942
mpagenkoaa3afe92021-05-21 16:20:58 +00001943func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001944 aVersion string) *voltha.ImageState {
1945 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001946 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001947 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001948 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001949 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1950 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1951 if aVersion == dh.pLastUpgradeImageState.Version {
1952 pImageState = dh.pLastUpgradeImageState
1953 } else { //state request for an image version different from last processed image version
1954 pImageState = &voltha.ImageState{
1955 Version: aVersion,
1956 //we cannot state something concerning this version
1957 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1958 Reason: voltha.ImageState_NO_ERROR,
1959 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1960 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001961 }
1962 }
mpagenko38662d02021-08-11 09:45:19 +00001963 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001964}
1965
1966func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1967 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001969 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001970 dh.lockUpgradeFsm.RLock()
1971 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001972 dh.lockUpgradeFsm.RUnlock()
1973 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001974 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001975 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1976 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1977 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1978 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1979 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1980 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001981 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1982 dh.upgradeCanceled = true
1983 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1984 }
mpagenko45586762021-10-01 08:30:22 +00001985 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001986 } else {
mpagenko45586762021-10-01 08:30:22 +00001987 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001988 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1989 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1990 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1991 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1992 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1993 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001994 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1995 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001996 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1997 //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 +00001998 }
1999}
2000
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002001func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
2002
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002003 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002004
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002005 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002006 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002007 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
2008 pDevEntry.MutexOnuImageStatus.Lock()
2009 pDevEntry.POnuImageStatus = onuImageStatus
2010 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002011
2012 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002013 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002014 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
2015 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002016 images, err := onuImageStatus.GetOnuImageStatus(ctx)
2017 pDevEntry.MutexOnuImageStatus.Lock()
2018 pDevEntry.POnuImageStatus = nil
2019 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002020 return images, err
2021}
2022
Himani Chawla6d2ae152020-09-02 13:11:20 +05302023// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002024// #####################################################################################
2025
2026// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302027// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002028
dbainbri4d3a0dc2020-12-02 00:33:42 +00002029func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002030 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
2031 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002032}
2033
2034// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002036
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002037 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038 var err error
2039
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002040 // populate what we know. rest comes later after mib sync
2041 dh.device.Root = false
2042 dh.device.Vendor = "OpenONU"
2043 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002044 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00002045 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002046
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002047 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002048
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002049 if !dh.IsReconciling() {
2050 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302051 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002052 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2053 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302054 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002055 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302056 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002057 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002058 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002059
Himani Chawla4d908332020-08-31 12:30:20 +05302060 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002061 dh.ponPortNumber = dh.device.ParentPortNo
2062
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002063 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2064 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2065 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002066 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002067 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302068 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002069
2070 /*
2071 self._pon = PonPort.create(self, self._pon_port_number)
2072 self._pon.add_peer(self.parent_id, self._pon_port_number)
2073 self.logger.debug('adding-pon-port-to-agent',
2074 type=self._pon.get_port().type,
2075 admin_state=self._pon.get_port().admin_state,
2076 oper_status=self._pon.get_port().oper_status,
2077 )
2078 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002079 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302080 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002081 var ponPortNo uint32 = 1
2082 if dh.ponPortNumber != 0 {
2083 ponPortNo = dh.ponPortNumber
2084 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002085
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002086 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002087 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002088 PortNo: ponPortNo,
2089 Label: fmt.Sprintf("pon-%d", ponPortNo),
2090 Type: voltha.Port_PON_ONU,
2091 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302092 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002093 PortNo: ponPortNo}}, // Peer port is parent's port number
2094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002095 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002096 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002097 e.Cancel(err)
2098 return
2099 }
2100 } else {
bseeniva8c4547f2026-01-30 16:30:30 +05302101 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002102 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002103 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002104}
2105
2106// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002108
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002109 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002110 var err error
2111 /*
2112 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2113 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2114 return nil
2115 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002116 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002117 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002118 e.Cancel(err)
2119 return
2120 }
2121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002122 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002124 // reconcilement will be continued after mib download is done
2125 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002126
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002127 /*
2128 ############################################################################
2129 # Setup Alarm handler
2130 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2131 device.serial_number)
2132 ############################################################################
2133 # Setup PM configuration for this device
2134 # Pass in ONU specific options
2135 kwargs = {
2136 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2137 'heartbeat': self.heartbeat,
2138 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2139 }
2140 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2141 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2142 self.logical_device_id, device.serial_number,
2143 grouped=True, freq_override=False, **kwargs)
2144 pm_config = self._pm_metrics.make_proto()
2145 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2146 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2147 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2148
2149 # Note, ONU ID and UNI intf set in add_uni_port method
2150 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2151 ani_ports=[self._pon])
2152
2153 # Code to Run OMCI Test Action
2154 kwargs_omci_test_action = {
2155 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2156 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2157 }
2158 serial_number = device.serial_number
2159 self._test_request = OmciTestRequest(self.core_proxy,
2160 self.omci_agent, self.device_id,
2161 AniG, serial_number,
2162 self.logical_device_id,
2163 exclusive=False,
2164 **kwargs_omci_test_action)
2165
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002166 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002167 else:
2168 self.logger.info('onu-already-activated')
2169 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002170
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002171 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002172}
2173
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002174// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002176
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002177 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
bseeniva0c06c862026-02-03 14:04:35 +05302178 onuIndication := e.Args[0].(*oop.OnuIndication)
2179 if err := dh.createInterface(ctx, onuIndication); err != nil {
2180 logger.Errorw(ctx, "failed to create interface", log.Fields{"device-id": dh.DeviceID, "error": err})
2181 e.Cancel(err)
2182 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002183 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184
2185 /*
2186 // Synchronous call to update device state - this method is run in its own go routine
2187 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2188 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002189 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 +00002190 return err
2191 }
2192 return nil
2193 */
2194}
2195
2196// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002198
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002199 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002200 var err error
2201
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002202 device := dh.device
2203 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002204 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002206 e.Cancel(err)
2207 return
2208 }
2209
2210 cloned := proto.Clone(device).(*voltha.Device)
bseeniva0c06c862026-02-03 14:04:35 +05302211
dbainbri4d3a0dc2020-12-02 00:33:42 +00002212 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
bseeniva0c06c862026-02-03 14:04:35 +05302213 if err := dh.UpdateInterface(ctx); err != nil {
2214 logger.Errorw(ctx, "failed to update interface", log.Fields{"device-id": dh.DeviceID, "error": err})
2215 e.Cancel(err)
2216 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002217 /*
2218 // Update the all ports state on that device to disable
2219 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002220 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002221 return er
2222 }
2223
2224 //Update the device oper state and connection status
2225 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2226 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2227 dh.device = cloned
2228
2229 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002230 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002231 return er
2232 }
2233
2234 //get the child device for the parent device
2235 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2236 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002237 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002238 return err
2239 }
2240 for _, onuDevice := range onuDevices.Items {
2241
2242 // Update onu state as down in onu adapter
2243 onuInd := oop.OnuIndication{}
2244 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002245 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002246 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2247 if er != nil {
2248 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002249 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002250 //Do not return here and continue to process other ONUs
2251 }
2252 }
2253 // * Discovered ONUs entries need to be cleared , since after OLT
2254 // is up, it starts sending discovery indications again* /
2255 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002256 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002257 return nil
2258 */
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002259 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002260}
2261
Himani Chawla6d2ae152020-09-02 13:11:20 +05302262// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002263// #################################################################################
2264
2265// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302266// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002267
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302268// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002270 dh.lockDevice.RLock()
2271 pOnuDeviceEntry := dh.pOnuOmciDevice
2272 if aWait && pOnuDeviceEntry == nil {
2273 //keep the read sema short to allow for subsequent write
2274 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002276 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2277 // so it might be needed to wait here for that event with some timeout
2278 select {
2279 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002281 return nil
2282 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002284 // if written now, we can return the written value without sema
2285 return dh.pOnuOmciDevice
2286 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002287 }
mpagenko3af1f032020-06-10 08:53:41 +00002288 dh.lockDevice.RUnlock()
2289 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002290}
2291
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302292// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2294 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002295 dh.lockDevice.Lock()
2296 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002297 dh.pOnuOmciDevice = apDeviceEntry
2298 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002299 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302300 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002301 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002302}
2303
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302304// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302305//
2306//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302307func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002308 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002309
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002311 if deviceEntry == nil {
2312 /* costum_me_map in python code seems always to be None,
2313 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2314 /* also no 'clock' argument - usage open ...*/
2315 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2317 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2318 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2319 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2320 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002321 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002323 // fire deviceEntry ready event to spread to possibly waiting processing
2324 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002326 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002328 }
2329 // might be updated with some error handling !!!
2330 return nil
2331}
2332
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002334 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002335 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2336
2337 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
bseeniva0c06c862026-02-03 14:04:35 +05302338 pDevEntry := dh.pOnuOmciDevice
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302339
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002343
khenaidoo42dcdfd2021-10-19 17:34:12 -04002344 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002346 OperStatus: voltha.OperStatus_ACTIVATING,
2347 ConnStatus: voltha.ConnectStatus_REACHABLE,
2348 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002349 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302351 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2352 }
2353 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2354 if dh.GetDeviceTechProfOnReboot() {
2355 pDevEntry.MutexPersOnuConfig.Lock()
2356 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2357 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302358 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302359 pDevEntry.MutexPersOnuConfig.Unlock()
2360 }
2361 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2362 if err := dh.StorePersistentData(ctx); err != nil {
2363 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2364 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002365 }
2366 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302367 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002369
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370 pDevEntry.MutexPersOnuConfig.RLock()
2371 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2372 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002373 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 +00002374 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002375 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302376
2377 //VOL-4965: Recover previously Activating ONU during reconciliation.
bseeniva33968f02026-01-30 18:49:48 +05302378 // Allow the ONU device to perform mib-reset and follow the standard startup process, if it was previously in the Activating state or
2379 // if its admin state was "up" before the ONU adapter restarted.
2380 pDevEntry.MutexPersOnuConfig.Lock()
2381 if dh.device.OperStatus == common.OperStatus_ACTIVATING || pDevEntry.SOnuPersistentData.PersAdminState == "up" {
2382 logger.Debugw(ctx, "Reconciling an ONU in previously activating state or admin state up, perform MIB reset and resume normal start up",
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302383 log.Fields{"device-id": dh.DeviceID})
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302384 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2385 pDevEntry.MutexPersOnuConfig.Unlock()
bseeniva33968f02026-01-30 18:49:48 +05302386 } else {
2387 pDevEntry.MutexPersOnuConfig.Unlock()
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302388 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002389 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002390 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002391 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002392 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002393 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2394 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2395 // 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 +00002396 // 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 +00002397 // so let's just try to keep it simple ...
2398 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002400 if err != nil || device == nil {
2401 //TODO: needs to handle error scenarios
2402 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2403 return errors.New("Voltha Device not found")
2404 }
2405 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002406
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002407 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002408 return err
mpagenko3af1f032020-06-10 08:53:41 +00002409 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002410 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302411 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2412 /* this might be a good time for Omci Verify message? */
2413 verifyExec := make(chan bool)
2414 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2415 dh.device.Id, pDevEntry.PDevOmciCC, false,
2416 true, true) //exclusive and allowFailure (anyway not yet checked)
2417 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002418
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302419 /* give the handler some time here to wait for the OMCi verification result
2420 after Timeout start and try MibUpload FSM anyway
2421 (to prevent stopping on just not supported OMCI verification from ONU) */
2422 select {
2423 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2424 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2425 case testresult := <-verifyExec:
2426 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2427 case <-dh.deviceDeleteCommChan:
2428 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2429 return nil
2430 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002431 }
2432
2433 /* In py code it looks earlier (on activate ..)
2434 # Code to Run OMCI Test Action
2435 kwargs_omci_test_action = {
2436 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2437 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2438 }
2439 serial_number = device.serial_number
2440 self._test_request = OmciTestRequest(self.core_proxy,
2441 self.omci_agent, self.device_id,
2442 AniG, serial_number,
2443 self.logical_device_id,
2444 exclusive=False,
2445 **kwargs_omci_test_action)
2446 ...
2447 # Start test requests after a brief pause
2448 if not self._test_request_started:
2449 self._test_request_started = True
2450 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2451 reactor.callLater(tststart, self._test_request.start_collector)
2452
2453 */
2454 /* which is then: in omci_test_request.py : */
2455 /*
2456 def start_collector(self, callback=None):
2457 """
2458 Start the collection loop for an adapter if the frequency > 0
2459
2460 :param callback: (callable) Function to call to collect PM data
2461 """
2462 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2463 if callback is None:
2464 callback = self.perform_test_omci
2465
2466 if self.lc is None:
2467 self.lc = LoopingCall(callback)
2468
2469 if self.default_freq > 0:
2470 self.lc.start(interval=self.default_freq / 10)
2471
2472 def perform_test_omci(self):
2473 """
2474 Perform the initial test request
2475 """
2476 ani_g_entities = self._device.configuration.ani_g_entities
2477 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2478 is not None else None
2479 self._entity_id = ani_g_entities_ids[0]
2480 self.logger.info('perform-test', entity_class=self._entity_class,
2481 entity_id=self._entity_id)
2482 try:
2483 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2484 result = yield self._device.omci_cc.send(frame)
2485 if not result.fields['omci_message'].fields['success_code']:
2486 self.logger.info('Self-Test Submitted Successfully',
2487 code=result.fields[
2488 'omci_message'].fields['success_code'])
2489 else:
2490 raise TestFailure('Test Failure: {}'.format(
2491 result.fields['omci_message'].fields['success_code']))
2492 except TimeoutError as e:
2493 self.deferred.errback(failure.Failure(e))
2494
2495 except Exception as e:
2496 self.logger.exception('perform-test-Error', e=e,
2497 class_id=self._entity_class,
2498 entity_id=self._entity_id)
2499 self.deferred.errback(failure.Failure(e))
2500
2501 */
2502
2503 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002505
mpagenko1cc3cb42020-07-27 15:24:38 +00002506 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2507 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2508 * 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 +05302509 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002510 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302511
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302513 // Breaking this part of code due to sca complexity
2514 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2515 return err
2516}
2517
2518func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002520 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 if pMibUlFsm.Is(mib.UlStDisabled) {
2522 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2523 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2524 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302525 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002526 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302527 //Determine ONU status and start/re-start MIB Synchronization tasks
2528 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002529 if pDevEntry.IsNewOnu() {
2530 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2531 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2532 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002533 }
Himani Chawla4d908332020-08-31 12:30:20 +05302534 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002535 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2536 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2537 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302538 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002539 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002540 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002541 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 "device-id": dh.DeviceID})
2544 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002545 }
2546 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2548 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002549 }
2550 return nil
2551}
2552
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002553func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002554 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002555 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302557 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002558
mpagenko900ee4b2020-10-12 11:56:34 +00002559 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2560 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2561 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002562 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002563 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002565 // abort: system behavior is just unstable ...
2566 return err
2567 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002568 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302569 if !dh.GetDeviceTechProfOnReboot() {
2570 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2571 }
mpagenko900ee4b2020-10-12 11:56:34 +00002572
2573 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002574 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002576 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2578 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002579 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002581
2582 //TODO!!! remove existing traffic profiles
2583 /* from py code, if TP's exist, remove them - not yet implemented
2584 self._tp = dict()
2585 # Let TP download happen again
2586 for uni_id in self._tp_service_specific_task:
2587 self._tp_service_specific_task[uni_id].clear()
2588 for uni_id in self._tech_profile_download_done:
2589 self._tech_profile_download_done[uni_id].clear()
2590 */
2591
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002594 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002595
mpagenkoe4782082021-11-25 12:04:26 +00002596 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002597 // abort: system behavior is just unstable ...
2598 return err
2599 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002600 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002602 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002604 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2605 OperStatus: voltha.OperStatus_DISCOVERED,
2606 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002607 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002610 // abort: system behavior is just unstable ...
2611 return err
2612 }
akashreddykb03dde02025-12-02 10:53:18 +05302613 if dh.GetDeviceTechProfOnReboot() {
2614 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2615 if err := dh.StorePersistentData(ctx); err != nil {
2616 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2617 log.Fields{"device-id": dh.DeviceID, "err": err})
2618 }
2619 }
mpagenko3af1f032020-06-10 08:53:41 +00002620 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002622 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002623 return nil
2624}
2625
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002626func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002627 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2628 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2629 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2630 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002631 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002632
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302634 //VOL-5260: During race conditions when adoptDevice has not yet completed
2635 // and deleteDevice is issued , returning error will further prevent clean up
2636 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002637 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302638 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2639 logger.Error(ctx, errMsg)
2640 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002641 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002642 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002643 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002644 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002645 pDevEntry.MutexOnuImageStatus.RLock()
2646 if pDevEntry.POnuImageStatus != nil {
2647 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002648 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002650
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002651 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002652 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002653 }
2654 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002655 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002656 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002658 }
mpagenko101ac942021-11-16 15:01:29 +00002659 //stop any deviceHandler reconcile processing (if running)
2660 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002661 //port lock/unlock FSM's may be active
2662 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002664 }
2665 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002667 }
2668 //techProfile related PonAniConfigFsm FSM may be active
2669 if dh.pOnuTP != nil {
2670 // should always be the case here
2671 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002672 if dh.pOnuTP.PAniConfigFsm != nil {
2673 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2674 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002675 }
mpagenko900ee4b2020-10-12 11:56:34 +00002676 }
2677 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002678 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002679 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002681 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002682 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002683 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002684 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002685 } else {
2686 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002687 }
2688 }
2689 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302690
2691 dh.mutexCollectorFlag.Lock()
2692 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2693 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002694 // Stop collector routine
2695 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302696 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002697 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302698 dh.mutexCollectorFlag.Unlock()
2699
2700 dh.mutextAlarmManagerFlag.Lock()
2701 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2702 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302703 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302704 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302705 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302706 dh.mutextAlarmManagerFlag.Unlock()
2707
2708 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2709 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2710 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002711 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302712 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002713 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302714 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302715
Girish Gowdrae95687a2021-09-08 16:30:58 -07002716 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2717
mpagenko80622a52021-02-09 16:53:23 +00002718 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002720 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002721 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002723 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002724 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002725 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2726 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2727 // (even though it may also run into direct cancellation, a bit hard to verify here)
2728 // so don't set 'dh.upgradeCanceled = true' here!
2729 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2730 }
mpagenko38662d02021-08-11 09:45:19 +00002731 }
mpagenko80622a52021-02-09 16:53:23 +00002732
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002734 return nil
2735}
2736
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302737//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2739 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 +05302740
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002741 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002743 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002745 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002746 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002748
mpagenkoa40e99a2020-11-17 13:50:39 +00002749 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2750 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2751 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2752 * disable/enable toggling here to allow traffic
2753 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2754 * like the py comment says:
2755 * # start by locking all the unis till mib sync and initial mib is downloaded
2756 * # this way we can capture the port down/up events when we are ready
2757 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302758
mpagenkoa40e99a2020-11-17 13:50:39 +00002759 // Init Uni Ports to Admin locked state
2760 // *** should generate UniLockStateDone event *****
2761 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002763 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002765 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002766 }
2767}
2768
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302769//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2771 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302772 /* Mib download procedure -
2773 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2774 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002776 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002778 return
2779 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302781 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 if pMibDlFsm.Is(mib.DlStDisabled) {
2783 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2784 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 +05302785 // maybe try a FSM reset and then again ... - TODO!!!
2786 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002787 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302788 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2790 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302791 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002792 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302793 //Begin MIB data download (running autonomously)
2794 }
2795 }
2796 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302799 // maybe try a FSM reset and then again ... - TODO!!!
2800 }
2801 /***** Mib download started */
2802 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302804 }
2805}
2806
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302807//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302809 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002810 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2811 if pDevEntry == nil {
2812 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2813 return
2814 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002816 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002817 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002818 // update device info in core
2819 pDevEntry.MutexPersOnuConfig.RLock()
2820 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2821 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2822 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2823 pDevEntry.MutexPersOnuConfig.RUnlock()
2824 dh.logicalDeviceID = dh.DeviceID
2825 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2826 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2827 }
2828 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002829 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2830 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2831 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2832 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002833 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002835 ConnStatus: voltha.ConnectStatus_REACHABLE,
2836 OperStatus: voltha.OperStatus_ACTIVE,
2837 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302838 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302840 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302842 }
2843 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302844 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002845 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302846 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002847 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002848
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002849 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002850 var waitForOmciProcessor sync.WaitGroup
2851 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002852 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002853 go dh.StartCollector(ctx, &waitForOmciProcessor)
2854 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002855 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 if !dh.GetAlarmManagerIsRunning(ctx) {
2857 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002858 }
2859
Girish Gowdrae95687a2021-09-08 16:30:58 -07002860 // Start flow handler routines per UNI
2861 for _, uniPort := range dh.uniEntityMap {
2862 // only if this port was enabled for use by the operator at startup
2863 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2864 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2865 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2866 }
2867 }
2868 }
2869
Girish Gowdrae0140f02021-02-02 16:55:09 -08002870 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002872 // There is no way we should be landing here, but if we do then
2873 // there is nothing much we can do about this other than log error
2874 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2875 }
2876
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002878
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002879 pDevEntry.MutexPersOnuConfig.RLock()
2880 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2881 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302882 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002884 dh.mutexForDisableDeviceRequested.Lock()
2885 dh.disableDeviceRequested = true
2886 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002887 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002888 // reconcilement will be continued after ani config is done
2889 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002890 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002891 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002892 dh.mutexForDisableDeviceRequested.RLock()
2893 if !dh.disableDeviceRequested {
2894 if dh.pUnlockStateFsm == nil {
2895 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2896 } else { //UnlockStateFSM already init
2897 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2898 dh.runUniLockFsm(ctx, false)
2899 }
2900 dh.mutexForDisableDeviceRequested.RUnlock()
2901 } else {
2902 dh.mutexForDisableDeviceRequested.RUnlock()
2903 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002904 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302905 }
2906}
2907
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302908//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2910 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302911
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302913 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2914 if dh.GetDeviceTechProfOnReboot() {
2915 if dh.CheckForDeviceTechProf(ctx) {
2916 go dh.DeviceFlowConfigOnReboot(ctx)
2917 }
2918 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002920 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2922 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002923 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002925 return
2926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 pDevEntry.MutexPersOnuConfig.Lock()
2928 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2929 pDevEntry.MutexPersOnuConfig.Unlock()
2930 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002933 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302934 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302935 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 +00002936 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002937 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302938
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002939 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302940
Himani Chawla26e555c2020-08-31 12:30:20 +05302941 }
2942}
2943
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302944//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002946 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002948
mpagenko44bd8362021-11-15 11:40:05 +00002949 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002950 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002952 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002953 OperStatus: voltha.OperStatus_UNKNOWN,
2954 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002955 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002957 }
2958
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002960 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002961 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002962
2963 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002965
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002967 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002969 return
2970 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971 pDevEntry.MutexPersOnuConfig.Lock()
2972 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2973 pDevEntry.MutexPersOnuConfig.Unlock()
2974 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002975 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002977 }
mpagenko900ee4b2020-10-12 11:56:34 +00002978}
2979
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302980//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002982 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002984 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002986 ConnStatus: voltha.ConnectStatus_REACHABLE,
2987 OperStatus: voltha.OperStatus_ACTIVE,
2988 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002989 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002991 }
2992
dbainbri4d3a0dc2020-12-02 00:33:42 +00002993 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002995 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002996 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002997
2998 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002999 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003002 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003004 return
3005 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006 pDevEntry.MutexPersOnuConfig.Lock()
3007 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
3008 pDevEntry.MutexPersOnuConfig.Unlock()
3009 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003010 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003012 }
mpagenko900ee4b2020-10-12 11:56:34 +00003013}
3014
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303015//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003016func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3017 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
3018 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04003019 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003020 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00003021 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003022 OperStatus: voltha.OperStatus_FAILED,
3023 }); err != nil {
3024 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
3025 }
3026}
3027
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
3029 if devEvent == cmn.OmciAniConfigDone {
3030 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003031 // attention: the device reason update is done based on ONU-UNI-Port related activity
3032 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003033 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003034 // 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 +00003035 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05303036 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003038 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
3039 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
3040 dh.mutexReconcilingFirstPassFlag.Lock()
3041 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303042 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00003043 dh.reconcilingFirstPass = false
3044 go dh.ReconcileDeviceFlowConfig(ctx)
3045 }
3046 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003047 }
3048 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003049 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003050 // attention: the device reason update is done based on ONU-UNI-Port related activity
3051 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003052 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003053 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3054 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003055 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003056 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303057}
3058
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003059func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003060 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303062 // attention: the device reason update is done based on ONU-UNI-Port related activity
3063 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303064
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3066 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003067 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003068 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003069 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003070 }
3071 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003072 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003073 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003074 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003075 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303076 }
mpagenkof1fc3862021-02-16 10:09:52 +00003077
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003078 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003079 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003081 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003082 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003083 }
3084 } else {
3085 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003087 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303088}
3089
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303090// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303092 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003094 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003095 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003096 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003098 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003099 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003100 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003101 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003102 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003103 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003104 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003105 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003106 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003107 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003108 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003109 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003110 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003111 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003112 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003113 case cmn.UniEnableStateFailed:
3114 {
3115 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3116 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003117 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003118 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003119 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003120 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003122 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003124 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003126 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003128 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003129 default:
3130 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003131 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003132 }
3133 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003134}
3135
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003137 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003138 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303139 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003140 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003141 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003142 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303143 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003144 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003145 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003146 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 +00003147 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003148 //store UniPort with the System-PortNumber key
3149 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003150 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003151 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003152 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003153 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003154 } //error logging already within UniPort method
3155 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303156 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003157 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003158 }
3159 }
3160}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003161
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3163 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003164 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003166 return
3167 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003168 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003169 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003170 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3171 for _, mgmtEntityID := range pptpInstKeys {
3172 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003174 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3175 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003176 }
3177 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003179 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003181 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3182 for _, mgmtEntityID := range veipInstKeys {
3183 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003184 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003185 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3186 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003187 }
3188 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003189 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003190 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003192 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3193 for _, mgmtEntityID := range potsInstKeys {
3194 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003196 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3197 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003198 }
3199 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003201 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003202 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003203 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003204 return
3205 }
3206
mpagenko2c3f6c52021-11-23 11:22:10 +00003207 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3208 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3209 // 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 -07003210 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3211 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3212 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003213 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3214 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303215 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003216 for i := 0; i < int(uniCnt); i++ {
3217 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003218 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003219 }
3220}
3221
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3223func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003224 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303225 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003226 // with following remark:
3227 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3228 // # load on the core
3229
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003230 // 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 +00003231
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003232 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003233 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003234 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3235 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303236 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003238 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003239 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003240 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003241 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003242 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003243 PortNo: port.PortNo,
3244 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003245 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 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 -04003247 }
3248 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003249 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303250 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003251 }
mpagenko3af1f032020-06-10 08:53:41 +00003252 }
3253 }
3254}
3255
3256// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003257func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3258 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003259 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3260 for uniNo, uniPort := range dh.uniEntityMap {
3261 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003262
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003263 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3264 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303265 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003266 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003267 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003269 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003271 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003272 PortNo: port.PortNo,
3273 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003274 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003275 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 -04003276 }
3277 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003278 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303279 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003280 }
3281
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003282 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003283 }
3284}
3285
3286// ONU_Active/Inactive announcement on system KAFKA bus
3287// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303288func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003289 var de voltha.DeviceEvent
3290 eventContext := make(map[string]string)
3291 //Populating event context
3292 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003293 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003294 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003295 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003296 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003297 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 +00003298 }
3299 oltSerialNumber := parentDevice.SerialNumber
3300
3301 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3302 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3303 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303304 eventContext["olt-serial-number"] = oltSerialNumber
3305 eventContext["device-id"] = aDeviceID
3306 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003307 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003308 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3309 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003310 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3311 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003312 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3313 deviceEntry.MutexPersOnuConfig.RUnlock()
3314 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003315 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003316 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3317 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3318 } else {
3319 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3320 log.Fields{"device-id": aDeviceID})
3321 return
3322 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003323
3324 /* Populating device event body */
3325 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303326 de.ResourceId = aDeviceID
3327 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003328 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3329 de.Description = fmt.Sprintf("%s Event - %s - %s",
3330 cEventObjectType, cOnuActivatedEvent, "Raised")
3331 } else {
3332 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3333 de.Description = fmt.Sprintf("%s Event - %s - %s",
3334 cEventObjectType, cOnuActivatedEvent, "Cleared")
3335 }
3336 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303337 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003338 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303339 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003340 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303341 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303342 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003343}
3344
Himani Chawla4d908332020-08-31 12:30:20 +05303345// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003346func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303347 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003348 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303349 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003350 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003351 sFsmName = "LockStateFSM"
3352 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003353 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003354 sFsmName = "UnLockStateFSM"
3355 }
mpagenko3af1f032020-06-10 08:53:41 +00003356
bseenivacfcd8f72026-01-30 21:06:49 +05303357 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00003358 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003360 return
3361 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003363 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303364 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003365 dh.pLockStateFsm = pLSFsm
3366 } else {
3367 dh.pUnlockStateFsm = pLSFsm
3368 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003369 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003370 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003371 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003372 }
3373}
3374
3375// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003376func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003377 /* Uni Port lock/unlock procedure -
3378 ***** should run via 'adminDone' state and generate the argument requested event *****
3379 */
3380 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303381 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003382 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003383 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3384 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3386 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003387 }
3388 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003389 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003390 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3391 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3393 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003394 }
3395 }
3396 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3398 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003399 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003400 // maybe try a FSM reset and then again ... - TODO!!!
3401 } else {
3402 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003403 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003405 }
3406 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003407 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003408 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003409 // maybe try a FSM reset and then again ... - TODO!!!
3410 }
3411 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003413 // maybe try a FSM reset and then again ... - TODO!!!
3414 }
3415}
3416
mpagenko80622a52021-02-09 16:53:23 +00003417// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003418// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303419//
3420//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303422 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003423 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003425 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303427 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003428 }
bseeniva0b4286b2026-01-30 13:05:42 +05303429 fsmCtx := log.WithSpanFromContext(context.Background(), ctx)
3430 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(fsmCtx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003431 sFsmName, chUpgradeFsm)
3432 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003433 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003434 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3436 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003437 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003438 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303439 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003440 }
mpagenko59862f02021-10-11 08:53:18 +00003441 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003442 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3443 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003444 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3445 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003446 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003447 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003448 } else {
3449 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003450 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003451 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303452 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003453 }
3454 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"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 internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003458 }
3459 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303461 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003462 }
3463 return nil
3464}
3465
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3467func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003468 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003470 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003471 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3472 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003473 dh.pLastUpgradeImageState = apImageState
3474 dh.lockUpgradeFsm.Unlock()
3475 //signal upgradeFsm removed using non-blocking channel send
3476 select {
3477 case dh.upgradeFsmChan <- struct{}{}:
3478 default:
3479 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003481 }
mpagenko80622a52021-02-09 16:53:23 +00003482}
3483
mpagenko15ff4a52021-03-02 10:09:20 +00003484// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3485func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003487 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003489 return
3490 }
3491
3492 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003493 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003494 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003495 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3496 dh.lockUpgradeFsm.RUnlock()
3497 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3498 return
3499 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003500 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003501 if pUpgradeStatemachine != nil {
3502 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3503 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 UpgradeState := pUpgradeStatemachine.Current()
3505 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3506 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3507 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003508 // 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 +00003509 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003510 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3511 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003512 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003513 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003514 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003515 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3516 dh.upgradeCanceled = true
3517 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3518 }
mpagenko15ff4a52021-03-02 10:09:20 +00003519 return
3520 }
mpagenko59862f02021-10-11 08:53:18 +00003521 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003522 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3523 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003524 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003525 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003526 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3527 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003528 return
3529 }
3530 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003532 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3534 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003535 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3536 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003537 return
3538 }
3539 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003540 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003541 }
3542 } else {
3543 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 +00003544 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003545 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3546 dh.upgradeCanceled = true
3547 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3548 }
mpagenko1f8e8822021-06-25 14:10:21 +00003549 }
mpagenko15ff4a52021-03-02 10:09:20 +00003550 return
3551 }
mpagenko59862f02021-10-11 08:53:18 +00003552 dh.lockUpgradeFsm.RUnlock()
3553 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3554 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003555 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3556 dh.upgradeCanceled = true
3557 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3558 }
mpagenko59862f02021-10-11 08:53:18 +00003559 return
3560 }
3561 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3562 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3563 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3564 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3565 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3566 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3567 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003568 }
mpagenko15ff4a52021-03-02 10:09:20 +00003569 }
3570 }
3571 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003572 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003573 }
mpagenko59862f02021-10-11 08:53:18 +00003574 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003575}
3576
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303577// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003579
3580 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003581 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003582 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003583 kvbackend := &db.Backend{
3584 Client: dh.pOpenOnuAc.kvClient,
3585 StoreType: dh.pOpenOnuAc.KVStoreType,
3586 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003587 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003588 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3589 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003590
mpagenkoaf801632020-07-03 10:00:42 +00003591 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003592}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303593
3594//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003595func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303596 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003597
mpagenkodff5dda2020-08-28 11:52:01 +00003598 for _, field := range flow.GetOfbFields(apFlowItem) {
3599 switch field.Type {
3600 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3601 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003602 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003603 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3604 }
mpagenko01e726e2020-10-23 09:45:29 +00003605 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003606 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3607 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303608 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303610 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3611 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003612 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3613 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003614 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003615 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303616 return
mpagenkodff5dda2020-08-28 11:52:01 +00003617 }
3618 }
mpagenko01e726e2020-10-23 09:45:29 +00003619 */
mpagenkodff5dda2020-08-28 11:52:01 +00003620 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3621 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303622 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003623 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303624 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3625 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303626 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003627 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303629 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003630 }
3631 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3632 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303633 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003634 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303635 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003636 }
3637 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3638 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003639 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003640 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3641 }
3642 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
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-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3646 }
3647 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
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 "IPv4-DST": field.GetIpv4Dst()})
3651 }
3652 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
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-SRC": field.GetIpv4Src()})
3656 }
3657 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
3661 }
3662 /*
3663 default:
3664 {
3665 //all other entires ignored
3666 }
3667 */
3668 }
3669 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303670}
mpagenkodff5dda2020-08-28 11:52:01 +00003671
khenaidoo7d3c5582021-08-11 18:09:44 -04003672func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003673 for _, action := range flow.GetActions(apFlowItem) {
3674 switch action.Type {
3675 /* not used:
3676 case of.OfpActionType_OFPAT_OUTPUT:
3677 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003678 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003679 "Output": action.GetOutput()})
3680 }
3681 */
3682 case of.OfpActionType_OFPAT_PUSH_VLAN:
3683 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003684 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003685 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3686 }
3687 case of.OfpActionType_OFPAT_SET_FIELD:
3688 {
3689 pActionSetField := action.GetSetField()
3690 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003691 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003692 "OxcmClass": pActionSetField.Field.OxmClass})
3693 }
3694 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303695 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303697 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003698 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303699 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303701 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003702 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003703 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003704 "Type": pActionSetField.Field.GetOfbField().Type})
3705 }
3706 }
3707 /*
3708 default:
3709 {
3710 //all other entires ignored
3711 }
3712 */
3713 }
3714 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303715}
3716
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303717// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003719 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303720 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3721 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303722 var loSetPcp uint8
3723 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303724 var loIPProto uint32
3725 /* the TechProfileId is part of the flow Metadata - compare also comment within
3726 * OLT-Adapter:openolt_flowmgr.go
3727 * Metadata 8 bytes:
3728 * Most Significant 2 Bytes = Inner VLAN
3729 * Next 2 Bytes = Tech Profile ID(TPID)
3730 * Least Significant 4 Bytes = Port ID
3731 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3732 * subscriber related flows.
3733 */
3734
dbainbri4d3a0dc2020-12-02 00:33:42 +00003735 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303736 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003737 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003739 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303740 }
mpagenko551a4d42020-12-08 18:09:20 +00003741 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003742 loCookie := apFlowItem.GetCookie()
3743 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303744 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003745 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303746 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303747
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303748 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003749 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303750 if loIPProto == 2 {
3751 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3752 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003753 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003754 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303755 return nil
3756 }
mpagenko01e726e2020-10-23 09:45:29 +00003757 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003758 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003759
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303760 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3761 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003762 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003763 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003764 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3765 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3766 //TODO!!: Use DeviceId within the error response to rwCore
3767 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003768 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003769 }
3770 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003771 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003772 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303773 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3774 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3775 loSetVlan = loMatchVlan
3776 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 +00003777 } else {
3778 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3779 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3780 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303781 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003782 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003783 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003784 }
mpagenko9a304ea2020-12-16 15:54:01 +00003785
khenaidoo42dcdfd2021-10-19 17:34:12 -04003786 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003787 if apFlowMetaData != nil {
3788 meter = apFlowMetaData.Meters[0]
3789 }
mpagenkobc4170a2021-08-17 16:42:10 +00003790 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3791 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3792 // when different rules are requested concurrently for the same uni
3793 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3794 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3795 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003796 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3797 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003798 //SetUniFlowParams() may block on some rule that is suspended-to-add
3799 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003800 // Also the error is returned to caller via response channel
3801 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303802 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003803 dh.lockVlanConfig.RUnlock()
3804 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003805 return
mpagenkodff5dda2020-08-28 11:52:01 +00003806 }
mpagenkobc4170a2021-08-17 16:42:10 +00003807 dh.lockVlanConfig.RUnlock()
3808 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003809 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303810 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003811 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003812 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003813 if err != nil {
3814 *respChan <- err
3815 }
mpagenko01e726e2020-10-23 09:45:29 +00003816}
3817
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303818// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003819func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003820 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3821 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3822 //no extra check is done on the rule parameters
3823 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3824 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3825 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3826 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003827 // - 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 +00003828 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003830
3831 /* TT related temporary workaround - should not be needed anymore
3832 for _, field := range flow.GetOfbFields(apFlowItem) {
3833 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3834 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003835 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003836 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3837 if loIPProto == 2 {
3838 // 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 +00003839 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003841 return nil
3842 }
3843 }
3844 } //for all OfbFields
3845 */
3846
mpagenko9a304ea2020-12-16 15:54:01 +00003847 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003848 dh.lockVlanConfig.RLock()
3849 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3851 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003852 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3853 return
mpagenko01e726e2020-10-23 09:45:29 +00003854 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003855 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003856 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003857 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003858 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003859 // Push response on the response channel
3860 if respChan != nil {
3861 // 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
3862 select {
3863 case *respChan <- nil:
3864 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3865 default:
3866 }
3867 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003869}
3870
Himani Chawla26e555c2020-08-31 12:30:20 +05303871// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003872// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003873// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303875 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 +05303876 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003877
bseenivacfcd8f72026-01-30 21:06:49 +05303878 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenkodff5dda2020-08-28 11:52:01 +00003879 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003880 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3881 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003882 }
3883
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303884 if dh.pDeviceStateFsm.Current() == devStDown {
3885 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3886 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3887 }
3888
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003889 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3890 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303891 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003892 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003893 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3894 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3896 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003897 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003898 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3899 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003900 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3901 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003903 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303904 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003905 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003906 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3907 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003908 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003909 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003910 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3911 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003912 }
3913 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003914 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 "device-id": dh.DeviceID})
3916 return fmt.Errorf("uniVlanConfigFsm invalid 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 could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003920 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3921 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003922 }
3923 return nil
3924}
3925
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303926// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003927// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003928func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003929 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003930 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003931 for _, uniPort := range dh.uniEntityMap {
3932 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003933 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003934 pCurrentUniPort = uniPort
3935 break //found - end search loop
3936 }
3937 }
3938 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003939 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003940 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003941 return
3942 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003944}
3945
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303946// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003947func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003948 //TODO!! verify and start pending flow configuration
3949 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3950 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303951 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003952 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003953 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003954 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003955 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003957 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003958 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003959 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003960 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3961 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003962 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003963 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003964 } else {
3965 /***** UniVlanConfigFsm continued */
3966 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3968 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003969 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003970 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3971 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003972 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003974 } else {
3975 /***** UniVlanConfigFsm continued */
3976 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003977 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3978 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003979 }
mpagenkodff5dda2020-08-28 11:52:01 +00003980 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003981 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003982 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3983 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003984 }
3985 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003986 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 +00003987 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3988 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003989 }
3990 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003991 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003992 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003993 }
mpagenkof1fc3862021-02-16 10:09:52 +00003994 } else {
3995 dh.lockVlanConfig.RUnlock()
3996 }
mpagenkodff5dda2020-08-28 11:52:01 +00003997}
3998
Akash Soni3de0e062024-12-11 16:37:26 +05303999// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
4000func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
4001 dh.lockVlanConfig.Lock()
4002 defer dh.lockVlanConfig.Unlock()
4003
4004 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
4005 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
4006 if pVlanFilterStatemachine != nil {
4007 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4008 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
4009 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
4010 })
4011 } else {
4012 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
4013 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
4014 })
4015 }
4016 } else {
4017 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
4018 "device-id": dh.DeviceID, "UniPort": uniID,
4019 })
4020 }
4021 } else {
4022 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
4023 "device-id": dh.DeviceID, "UniPort": uniID,
4024 })
4025 }
4026}
4027
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304028// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00004029// 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 +00004030func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00004031 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004032 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00004033 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00004034 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004035 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00004036 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00004037}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004038
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304039// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004040func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00004041 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
4042 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
4043 // obviously then parallel processing on the cancel must be avoided
4044 // deadline context to ensure completion of background routines waited for
4045 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4046 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4047 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304048 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004049
Akash Soni840f8d62024-12-11 19:37:06 +05304050 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4051 if err != nil {
4052 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4053 return err
4054 }
4055 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004056}
4057
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304058// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4059// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004060func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4061 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004062
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004063 if dh.IsReconciling() {
bseeniva8c4547f2026-01-30 16:30:30 +05304064 logger.Debug(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004065 return nil
4066 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004067 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004068
bseenivacfcd8f72026-01-30 21:06:49 +05304069 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004070 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4072 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004073 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004074 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004075
mpagenkof1fc3862021-02-16 10:09:52 +00004076 if aWriteToKvStore {
4077 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4078 }
4079 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004080}
4081
dbainbri4d3a0dc2020-12-02 00:33:42 +00004082func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004083 defer cancel() //ensure termination of context (may be pro forma)
4084 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004085 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004086 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004087}
4088
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304089// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4090//
4091// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004092func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4093 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4094 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4095 dh.mutexDeviceReason.Lock()
4096 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004097 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004098 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004099 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004100 DeviceId: dh.DeviceID,
4101 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004102 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004103 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004104 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004105 return err
4106 }
mpagenkoe4782082021-11-25 12:04:26 +00004107 } else {
4108 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 +00004109 }
mpagenkoe4782082021-11-25 12:04:26 +00004110 dh.deviceReason = deviceReason
4111 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4112 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004113 return nil
4114}
4115
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004116func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
bseenivacfcd8f72026-01-30 21:06:49 +05304117 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004118 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004119 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4120 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004121 }
mpagenkof1fc3862021-02-16 10:09:52 +00004122 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004123}
4124
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304125func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4126 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4127 if pDevEntry != nil {
4128 pDevEntry.MutexPersOnuConfig.Lock()
4129 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4130 pDevEntry.MutexPersOnuConfig.Unlock()
4131 } else {
4132 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4133 }
4134}
4135
4136func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4137 rebootFlag := false
4138 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4139 if pDevEntry != nil {
4140 pDevEntry.MutexPersOnuConfig.RLock()
4141 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4142 pDevEntry.MutexPersOnuConfig.RUnlock()
4143 } else {
4144 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4145 }
4146 return rebootFlag
4147}
4148
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004149// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004150// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004151func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4152 dh.lockDevice.RLock()
4153 defer dh.lockDevice.RUnlock()
4154 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004155 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004156 }
4157 return 0, errors.New("error-fetching-uni-port")
4158}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004159
4160// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004161func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4162 var errorsList []error
4163 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 -08004164
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004165 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4166 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4167 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4168
4169 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4170 // successfully.
4171 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4172 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4173 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004174 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 -08004175 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004176 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004177 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004178 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004179}
4180
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004181func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4182 var err error
4183 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004184 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004185
4186 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004187 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004188 errorsList = append(errorsList, err)
4189 }
4190 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004191 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004192
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004193 return errorsList
4194}
4195
4196func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4197 var err error
4198 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004199 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004200 // Check if group metric related config is updated
4201 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004202 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4203 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4204 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004205
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004206 if ok && m.Frequency != v.GroupFreq {
4207 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004208 errorsList = append(errorsList, err)
4209 }
4210 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004211 if ok && m.Enabled != v.Enabled {
4212 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004213 errorsList = append(errorsList, err)
4214 }
4215 }
4216 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004217 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004218 return errorsList
4219}
4220
4221func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4222 var err error
4223 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004224 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004225 // Check if standalone metric related config is updated
4226 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004227 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4228 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4229 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004230
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004231 if ok && m.Frequency != v.SampleFreq {
4232 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004233 errorsList = append(errorsList, err)
4234 }
4235 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004236 if ok && m.Enabled != v.Enabled {
4237 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004238 errorsList = append(errorsList, err)
4239 }
4240 }
4241 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004242 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004243 return errorsList
4244}
4245
4246// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004247func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004248 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304249 dh.RLockMutexDeletionInProgressFlag()
4250 if dh.GetDeletionInProgress() {
4251 logger.Warnw(ctx, "Device deletion in progress - avoid starting metrics collector routine", log.Fields{"device-id": dh.device.Id})
4252 dh.RUnlockMutexDeletionInProgressFlag()
4253 return
4254 }
4255 // Set collectorIsRunning flag to true while still holding deviceDeletionFlag lock,
4256 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the collector routine if this flag is not yet set
4257 dh.setCollectorIsRunning(true)
4258 dh.RUnlockMutexDeletionInProgressFlag()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004259
4260 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004261 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304262 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004263 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004264 // Initialize the next metric collection time.
4265 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4266 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004267 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304268 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4269 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004270 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304271
Girish Gowdrae09a6202021-01-12 18:10:59 -08004272 select {
4273 case <-dh.stopCollector:
4274 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004275 // Stop the L2 PM FSM
4276 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004277 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4278 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4279 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004280 }
4281 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004282 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004283 }
4284 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004285 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4286 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004287 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004288 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4289 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004290 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004291
Girish Gowdrae09a6202021-01-12 18:10:59 -08004292 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304293 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004294 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4295 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4296 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4297 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004298 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004299 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4300 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004301 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004302 } else {
4303 if dh.pmConfigs.Grouped { // metrics are managed as a group
4304 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004305 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004306
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004307 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4308 // 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 -08004309 // 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 +00004310 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4311 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004312 }
4313 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004314 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4315 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4316 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4317 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004318 }
4319 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004320 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004321
4322 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004323 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4324 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4325 // 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 -08004326 // 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 +00004327 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004328 prevInternal := g.NextCollectionInterval
4329 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004330 }
4331 }
4332 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004333 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4334 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4335 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004336 prevInternal := m.NextCollectionInterval
4337 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004338 }
4339 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004340 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004341 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004342 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004343 } */
4344 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004345 }
4346 }
4347}
kesavandfdf77632021-01-26 23:40:33 -05004348
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304349//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304350func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4351
4352 singleValResp := extension.SingleSetValueResponse{
4353 Response: &extension.SetValueResponse{
4354 Status: extension.SetValueResponse_OK,
4355 },
4356 }
4357
4358 return &singleValResp
4359}
4360
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004361func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004362
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004363 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4364 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004365}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004366
Himani Chawla43f95ff2021-06-03 00:24:12 +05304367func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4368 if dh.pOnuMetricsMgr == nil {
4369 return &extension.SingleGetValueResponse{
4370 Response: &extension.GetValueResponse{
4371 Status: extension.GetValueResponse_ERROR,
4372 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4373 },
4374 }
4375 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304376 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304377 return resp
4378}
4379
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004380func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4381
4382 var err error
4383 var pDevOmciCC *cmn.OmciCC
4384 if dh.pOnuOmciDevice == nil {
4385 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4386 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4387 } else {
4388 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4389 if pDevOmciCC == nil {
4390 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4391 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4392 }
4393 }
4394 if err != nil {
4395 return &extension.SingleGetValueResponse{
4396 Response: &extension.GetValueResponse{
4397 Status: extension.GetValueResponse_ERROR,
4398 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4399 },
4400 },
4401 err
4402 }
4403 return pDevOmciCC.GetOmciCounters(), nil
4404}
4405
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304406//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004407func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4408 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004409 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004410 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004411 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004412}
4413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004414func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004415 var pAdapterFsm *cmn.AdapterFsm
4416 //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 +00004417 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004418 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004419 {
mpagenkofbf577d2021-10-12 11:44:33 +00004420 if dh.pOnuOmciDevice != nil {
4421 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4422 } else {
4423 return true //FSM not active - so there is no activity on omci
4424 }
mpagenkof1fc3862021-02-16 10:09:52 +00004425 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004426 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004427 {
mpagenkofbf577d2021-10-12 11:44:33 +00004428 if dh.pOnuOmciDevice != nil {
4429 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4430 } else {
4431 return true //FSM not active - so there is no activity on omci
4432 }
mpagenkof1fc3862021-02-16 10:09:52 +00004433 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004434 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004435 {
mpagenkofbf577d2021-10-12 11:44:33 +00004436 if dh.pLockStateFsm != nil {
4437 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4438 } else {
4439 return true //FSM not active - so there is no activity on omci
4440 }
mpagenkof1fc3862021-02-16 10:09:52 +00004441 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004442 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004443 {
mpagenkofbf577d2021-10-12 11:44:33 +00004444 if dh.pUnlockStateFsm != nil {
4445 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4446 } else {
4447 return true //FSM not active - so there is no activity on omci
4448 }
mpagenkof1fc3862021-02-16 10:09:52 +00004449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004450 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004451 {
mpagenkofbf577d2021-10-12 11:44:33 +00004452 if dh.pOnuMetricsMgr != nil {
4453 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004454 } else {
4455 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004456 }
4457 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004458 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004459 {
4460 dh.lockUpgradeFsm.RLock()
4461 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004462 if dh.pOnuUpradeFsm != nil {
4463 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4464 } else {
4465 return true //FSM not active - so there is no activity on omci
4466 }
mpagenko80622a52021-02-09 16:53:23 +00004467 }
mpagenkof1fc3862021-02-16 10:09:52 +00004468 default:
4469 {
4470 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004471 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004472 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004473 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004474 }
mpagenkofbf577d2021-10-12 11:44:33 +00004475 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4476 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4477 }
4478 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004479}
4480
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004481func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4482 for _, v := range dh.pOnuTP.PAniConfigFsm {
4483 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004484 return false
4485 }
4486 }
4487 return true
4488}
4489
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304490//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004491func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004492 dh.lockVlanConfig.RLock()
4493 defer dh.lockVlanConfig.RUnlock()
4494 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004495 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004496 return false
4497 }
4498 }
4499 return true //FSM not active - so there is no activity on omci
4500}
4501
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304502//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004503func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4504 dh.lockVlanConfig.RLock()
4505 defer dh.lockVlanConfig.RUnlock()
4506 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004507 if v.PAdaptFsm.PFsm != nil {
4508 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004509 return true //there is at least one VLAN FSM with some active configuration
4510 }
4511 }
4512 }
4513 return false //there is no VLAN FSM with some active configuration
4514}
4515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004516func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004517 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4518 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4519 return false
4520 }
4521 }
4522 // a further check is done to identify, if at least some data traffic related configuration exists
4523 // 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])
4524 return dh.checkUserServiceExists(ctx)
4525}
4526
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004527func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304528 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 +00004529 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004530 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004531 // TODO: fatal error reset ONU, delete deviceHandler!
4532 return
4533 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004534 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4535 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004536}
4537
4538func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4539 dh.mutexCollectorFlag.Lock()
4540 dh.collectorIsRunning = flagValue
4541 dh.mutexCollectorFlag.Unlock()
4542}
4543
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004544func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004545 dh.mutexCollectorFlag.RLock()
4546 flagValue := dh.collectorIsRunning
4547 dh.mutexCollectorFlag.RUnlock()
4548 return flagValue
4549}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304550
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304551func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4552 dh.mutextAlarmManagerFlag.Lock()
4553 dh.alarmManagerIsRunning = flagValue
4554 dh.mutextAlarmManagerFlag.Unlock()
4555}
4556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004557func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304558 dh.mutextAlarmManagerFlag.RLock()
4559 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004560 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304561 dh.mutextAlarmManagerFlag.RUnlock()
4562 return flagValue
4563}
4564
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004565func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004566 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
bseeniva596a5222026-01-23 19:26:11 +05304567 dh.RLockMutexDeletionInProgressFlag()
4568 if dh.GetDeletionInProgress() {
4569 logger.Warnw(ctx, "Device deletion in progress - avoid starting alarm manager", log.Fields{"device-id": dh.DeviceID})
4570 dh.RUnlockMutexDeletionInProgressFlag()
4571 return
4572 }
4573 // Set alarmManagerIsRunning flag to true while still holding deviceDeletionFlag lock,
4574 // to avoid potential race condition where resetFsm from DeleteDevice might avoid stopping the alarm manager if this flag is not yet set
4575 dh.setAlarmManagerIsRunning(true)
4576
4577 dh.RUnlockMutexDeletionInProgressFlag()
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304578
4579 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004580 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304581 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304582 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304583 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004584 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4585 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304586 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304587 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004588 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4589 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304590 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304591 }
4592}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004593
Girish Gowdrae95687a2021-09-08 16:30:58 -07004594func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4595 dh.mutexFlowMonitoringRoutineFlag.Lock()
4596 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004597 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004598 dh.isFlowMonitoringRoutineActive[uniID] = flag
4599}
4600
4601func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4602 dh.mutexFlowMonitoringRoutineFlag.RLock()
4603 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4604 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004605 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304606 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4607 return dh.isFlowMonitoringRoutineActive[uniID]
4608 }
4609 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004610}
4611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004612func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304613 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004614
Maninder7961d722021-06-16 22:10:28 +05304615 connectStatus := voltha.ConnectStatus_UNREACHABLE
4616 operState := voltha.OperStatus_UNKNOWN
4617
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004618 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004619 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004620 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004621 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004622 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004623 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304624 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004625 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4626 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4627 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4628 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4629 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4630 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4631 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4632 // However, a later refactoring of the functionality remains unaffected.
4633 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004634 if success {
bseenivacfcd8f72026-01-30 21:06:49 +05304635 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304636 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004637 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304638 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004639 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304640 switch onuDevEntry.SOnuPersistentData.PersOperState {
4641 case "up":
Maninderb5187552021-03-23 22:23:42 +05304642 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004643 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4644 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304645 operState = voltha.OperStatus_ACTIVE
4646 } else {
4647 operState = voltha.OperStatus_ACTIVATING
4648 }
4649 }
mgoudad611f4c2025-10-30 14:49:27 +05304650 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304651 operState = voltha.OperStatus_DISCOVERED
4652 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004653 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004654 logger.Debugw(ctx, "Core DeviceStateUpdate",
4655 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304656 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304657 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004658 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004659 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004660 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004661 ConnStatus: connectStatus,
4662 OperStatus: operState,
4663 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304664 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004665 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304666 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004667 } else {
Maninderb5187552021-03-23 22:23:42 +05304668 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004669 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304670
bseenivacfcd8f72026-01-30 21:06:49 +05304671 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304672 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004673 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004674 } else {
4675 onuDevEntry.MutexPersOnuConfig.RLock()
4676 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4677 connectStatus = voltha.ConnectStatus_REACHABLE
4678 }
4679 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304680 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004681 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004682 }
mpagenko101ac942021-11-16 15:01:29 +00004683 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004684 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004685 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004686 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304687
bseenivacfcd8f72026-01-30 21:06:49 +05304688 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304689 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004690 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004691 } else {
4692 onuDevEntry.MutexPersOnuConfig.RLock()
4693 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4694 connectStatus = voltha.ConnectStatus_REACHABLE
4695 }
4696 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304697 }
4698
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004699 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304700
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004701 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004702 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004703 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004704 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004705 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004706
bseenivacfcd8f72026-01-30 21:06:49 +05304707 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, false); onuDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004708 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4709 } else {
4710 onuDevEntry.MutexReconciledTpInstances.Lock()
bseeniva71b1b662026-02-12 19:07:50 +05304711 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]*ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004712 onuDevEntry.MutexReconciledTpInstances.Unlock()
4713 }
bseeniva33968f02026-01-30 18:49:48 +05304714 dh.chReconcilingStopped <- struct{}{}
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004715 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004716 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004717 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304718 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004719 dh.reconciling = cSkipOnuConfigReconciling
4720 } else {
4721 dh.reconciling = cOnuConfigReconciling
4722 }
4723 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004724}
4725
mpagenko101ac942021-11-16 15:01:29 +00004726func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304727 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004728 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004729 dh.sendChReconcileFinished(success)
4730 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4731 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4732 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004733 } else {
mpagenko101ac942021-11-16 15:01:29 +00004734 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004735 }
4736}
4737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004738func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004739 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004740 defer dh.mutexReconcilingFlag.RUnlock()
4741 return dh.reconciling != cNoReconciling
4742}
4743
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004744func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004745 dh.mutexReconcilingFlag.RLock()
4746 defer dh.mutexReconcilingFlag.RUnlock()
4747 return dh.reconciling == cSkipOnuConfigReconciling
4748}
4749
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004750func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4751 dh.mutexReconcilingFirstPassFlag.Lock()
4752 dh.reconcilingFirstPass = value
4753 dh.mutexReconcilingFirstPassFlag.Unlock()
4754}
4755
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004756func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4757 dh.mutexReconcilingReasonUpdate.Lock()
4758 dh.reconcilingReasonUpdate = value
4759 dh.mutexReconcilingReasonUpdate.Unlock()
4760}
4761
4762func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4763 dh.mutexReconcilingReasonUpdate.RLock()
4764 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4765 return dh.reconcilingReasonUpdate
4766}
4767
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004768func (dh *deviceHandler) getDeviceReason() uint8 {
4769 dh.mutexDeviceReason.RLock()
4770 value := dh.deviceReason
4771 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004772 return value
4773}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004774
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004775func (dh *deviceHandler) GetDeviceReasonString() string {
4776 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004777}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004778
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004779func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004780 dh.mutexReadyForOmciConfig.Lock()
4781 dh.readyForOmciConfig = flagValue
4782 dh.mutexReadyForOmciConfig.Unlock()
4783}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004784func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004785 dh.mutexReadyForOmciConfig.RLock()
4786 flagValue := dh.readyForOmciConfig
4787 dh.mutexReadyForOmciConfig.RUnlock()
4788 return flagValue
4789}
Maninder7961d722021-06-16 22:10:28 +05304790
4791func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004792 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304793 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004794 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304795 }
4796
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004797 logger.Debugw(ctx, "Core DeviceStateUpdate",
4798 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004799 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004800 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004801 ConnStatus: connectStatus,
4802 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4803 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304804 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004805 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304806 }
bseeniva4714cee2026-01-30 16:21:47 +05304807 context := make(map[string]string)
4808 context["device-id"] = dh.DeviceID
4809 context["onu-serial-number"] = dh.device.SerialNumber
4810 context["parent-id"] = dh.parentID
4811
4812 deviceEvent := &voltha.DeviceEvent{
4813 ResourceId: dh.DeviceID,
4814 DeviceEventName: cmn.OnuReconcileFailed,
4815 Description: cmn.OnuReconcileFailedAbortedDesc,
4816 Context: context,
4817 }
4818 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4819 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
Maninder7961d722021-06-16 22:10:28 +05304820}
khenaidoo7d3c5582021-08-11 18:09:44 -04004821
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304822func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4823 if techProfInstLoadFailed {
4824 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4825 logger.Errorw(ctx, "unable to update device reason to core",
4826 log.Fields{"device-id": dh.DeviceID, "Err": err})
4827 }
4828 context := make(map[string]string)
4829 context["device-id"] = dh.DeviceID
4830 context["onu-serial-number"] = dh.device.SerialNumber
4831 context["parent-id"] = dh.parentID
4832
4833 // Send event on flow configuration failure so that corrective action can be triggered from NB
4834 deviceEvent := &voltha.DeviceEvent{
4835 ResourceId: dh.DeviceID,
4836 DeviceEventName: cmn.OnuFlowConfigFailed,
4837 Description: cmn.OnuFlowConfigFailedDesc,
4838 Context: context,
4839 }
4840 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4841 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4842 }
4843}
4844
khenaidoo7d3c5582021-08-11 18:09:44 -04004845/*
4846Helper functions to communicate with Core
4847*/
4848
4849func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4850 cClient, err := dh.coreClient.GetCoreServiceClient()
4851 if err != nil || cClient == nil {
4852 return nil, err
4853 }
4854 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4855 defer cancel()
4856 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304857 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004858}
4859
khenaidoo42dcdfd2021-10-19 17:34:12 -04004860func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004861 cClient, err := dh.coreClient.GetCoreServiceClient()
4862 if err != nil || cClient == nil {
4863 return err
4864 }
4865 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4866 defer cancel()
4867 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004868 logger.Debugw(subCtx, "device-updated-in-core",
4869 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004870 return err
4871}
4872
4873func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4874 cClient, err := dh.coreClient.GetCoreServiceClient()
4875 if err != nil || cClient == nil {
4876 return err
4877 }
4878 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4879 defer cancel()
4880 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004881 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4882 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004883 return err
4884}
4885
4886func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4887 cClient, err := dh.coreClient.GetCoreServiceClient()
4888 if err != nil || cClient == nil {
4889 return err
4890 }
4891 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4892 defer cancel()
4893 _, err = cClient.DeviceUpdate(subCtx, device)
4894 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4895 return err
4896}
4897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004898func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004899 cClient, err := dh.coreClient.GetCoreServiceClient()
4900 if err != nil || cClient == nil {
4901 return err
4902 }
4903 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4904 defer cancel()
4905 _, err = cClient.PortCreated(subCtx, port)
4906 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4907 return err
4908}
4909
khenaidoo42dcdfd2021-10-19 17:34:12 -04004910func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004911 cClient, err := dh.coreClient.GetCoreServiceClient()
4912 if err != nil || cClient == nil {
4913 return err
4914 }
4915 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4916 defer cancel()
4917 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004918 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 -04004919 return err
4920}
4921
khenaidoo42dcdfd2021-10-19 17:34:12 -04004922func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004923 cClient, err := dh.coreClient.GetCoreServiceClient()
4924 if err != nil || cClient == nil {
4925 return err
4926 }
4927 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4928 defer cancel()
4929 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004930 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 -04004931 return err
4932}
4933
4934/*
4935Helper functions to communicate with parent adapter
4936*/
4937
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004938func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4939 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4940
4941 var request = ia.TechProfileInstanceRequestMessage{
4942 DeviceId: dh.DeviceID,
4943 TpInstancePath: aTpPath,
4944 ParentDeviceId: dh.parentID,
4945 ParentPonPort: dh.device.ParentPortNo,
4946 OnuId: dh.device.ProxyAddress.OnuId,
4947 UniId: uint32(aUniID),
4948 }
4949
4950 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004951 if err != nil || pgClient == nil {
4952 return nil, err
4953 }
4954 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4955 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004956 logger.Debugw(subCtx, "get-tech-profile-instance",
bseeniva71b1b662026-02-12 19:07:50 +05304957 log.Fields{"device-id": dh.device.Id, "tp-path": request.TpInstancePath, "uni-id": request.UniId, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004958 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004959}
4960
Girish Gowdrae95687a2021-09-08 16:30:58 -07004961// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4962// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4963func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
bseeniva8c4547f2026-01-30 16:30:30 +05304964 logger.Debugw(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004965 dh.setFlowMonitoringIsRunning(uniID, true)
4966 for {
4967 select {
4968 // block on the channel to receive an incoming flow
4969 // process the flow completely before proceeding to handle the next flow
4970 case flowCb := <-dh.flowCbChan[uniID]:
4971 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304972 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004973 respChan := make(chan error)
4974 if flowCb.addFlow {
4975 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4976 } else {
4977 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4978 }
4979 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304980 select {
4981
4982 case msg := <-respChan:
4983 *flowCb.respChan <- msg
4984 // response sent successfully
4985 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4986 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4987 case <-flowCb.ctx.Done():
4988 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4989 // Optionally, you can handle cleanup or logging here
4990 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4991 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4992 if pVlanFilterStatemachine != nil {
4993
4994 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4995 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
4996 log.Fields{"device-id": dh.DeviceID, "err": err})
4997
4998 }
4999
5000 }
5001 }
5002
5003 ctx2 := context.Background()
5004 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
5005 if metadata == 0 {
5006 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
5007 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5008 continue
5009 }
5010 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
5011
5012 if TpID == uint16(0) {
5013 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
5014 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
5015 continue
5016 }
5017 if dh.pOnuTP != nil {
5018 // should always be the case here
5019 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
5020 if dh.pOnuTP.PAniConfigFsm != nil {
5021 uniTP := avcfg.UniTP{
5022 UniID: flowCb.uniPort.UniID,
5023 TpID: uint8(TpID),
5024 }
5025 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
5026 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
5027 }
5028 }
5029 }
5030
5031 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07005032 case <-dh.stopFlowMonitoringRoutine[uniID]:
5033 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
5034 dh.setFlowMonitoringIsRunning(uniID, false)
5035 return
5036 }
5037 }
5038}
5039
kesavand011d5162021-11-25 19:21:06 +05305040func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
5041 request.ParentDeviceId = dh.GetProxyAddressID()
5042 request.ChildDeviceId = dh.DeviceID
5043 request.ProxyAddress = dh.GetProxyAddress()
5044 request.ConnectStatus = common.ConnectStatus_REACHABLE
5045
5046 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5047 if err != nil || pgClient == nil {
5048 return err
5049 }
5050 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5051 defer cancel()
5052 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
5053 _, err = pgClient.ProxyOmciRequests(subCtx, request)
5054 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00005055 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
5056 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05305057 }
5058 return err
5059}
5060
khenaidoo42dcdfd2021-10-19 17:34:12 -04005061func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04005062 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
5063 if err != nil || pgClient == nil {
5064 return err
5065 }
5066 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
5067 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005068 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005069 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04005070 _, err = pgClient.ProxyOmciRequest(subCtx, request)
5071 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005072 if status.Code(err) == codes.Unavailable {
5073 dh.setOltAvailable(false)
5074 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00005075 logger.Errorw(ctx, "omci-failure",
5076 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005077 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005078 }
5079 return err
5080}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005081
bseeniva71b1b662026-02-12 19:07:50 +05305082func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst *tech_profile.TechProfileInstance) error {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005083 // Check if there are additional TCONT instances necessary/available
5084 pDevEntry.MutexPersOnuConfig.Lock()
5085 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5086 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5087 pDevEntry.MutexPersOnuConfig.Unlock()
5088 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5089 logger.Debugw(ctx, "checking available TCONT instances",
5090 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5091 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5092 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5093 log.Fields{"device-id": dh.device.Id})
5094 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305095 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005096 }
5097 } else {
5098 pDevEntry.MutexPersOnuConfig.Unlock()
5099 }
5100 // Check if there are enough PrioQueue instances available
5101 if dh.pOnuTP != nil {
5102 var numberOfUsPrioQueueDbInsts int
5103
5104 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5105 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305106 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005107 numberOfUsPrioQueueDbInsts++
5108 }
5109 }
5110 // Check if there is an upstream PriorityQueue instance available for each Gem port
5111 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5112 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5113 log.Fields{"device-id": dh.DeviceID,
5114 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5115 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5116 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5117
5118 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5119 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5120 log.Fields{"device-id": dh.device.Id})
5121 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305122 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 +00005123 }
5124 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5125 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5126 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5127 } else {
5128 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5129 log.Fields{"device-id": dh.DeviceID})
5130 }
5131 return nil
5132}
5133
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005134// GetDeviceID - TODO: add comment
5135func (dh *deviceHandler) GetDeviceID() string {
5136 return dh.DeviceID
5137}
5138
5139// GetProxyAddressID - TODO: add comment
5140func (dh *deviceHandler) GetProxyAddressID() string {
5141 return dh.device.ProxyAddress.GetDeviceId()
5142}
5143
5144// GetProxyAddressType - TODO: add comment
5145func (dh *deviceHandler) GetProxyAddressType() string {
5146 return dh.device.ProxyAddress.GetDeviceType()
5147}
5148
5149// GetProxyAddress - TODO: add comment
5150func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5151 return dh.device.ProxyAddress
5152}
5153
5154// GetEventProxy - TODO: add comment
5155func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5156 return dh.EventProxy
5157}
5158
5159// GetOmciTimeout - TODO: add comment
5160func (dh *deviceHandler) GetOmciTimeout() int {
5161 return dh.pOpenOnuAc.omciTimeout
5162}
5163
5164// GetAlarmAuditInterval - TODO: add comment
5165func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5166 return dh.pOpenOnuAc.alarmAuditInterval
5167}
5168
5169// GetDlToOnuTimeout4M - TODO: add comment
5170func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5171 return dh.pOpenOnuAc.dlToOnuTimeout4M
5172}
5173
5174// GetUniEntityMap - TODO: add comment
5175func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5176 return &dh.uniEntityMap
5177}
5178
5179// GetPonPortNumber - TODO: add comment
5180func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5181 return &dh.ponPortNumber
5182}
5183
5184// GetUniVlanConfigFsm - TODO: add comment
5185func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005186 dh.lockVlanConfig.RLock()
5187 value := dh.UniVlanConfigFsmMap[uniID]
5188 dh.lockVlanConfig.RUnlock()
5189 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005190}
5191
5192// GetOnuAlarmManager - TODO: add comment
5193func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5194 return dh.pAlarmMgr
5195}
5196
5197// GetOnuMetricsManager - TODO: add comment
5198func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5199 return dh.pOnuMetricsMgr
5200}
5201
5202// GetOnuTP - TODO: add comment
5203func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5204 return dh.pOnuTP
5205}
5206
5207// GetBackendPathPrefix - TODO: add comment
5208func (dh *deviceHandler) GetBackendPathPrefix() string {
5209 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5210}
5211
5212// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305213func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005214 return dh.pOnuIndication
5215}
5216
5217// RLockMutexDeletionInProgressFlag - TODO: add comment
5218func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5219 dh.mutexDeletionInProgressFlag.RLock()
5220}
5221
5222// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5223func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5224 dh.mutexDeletionInProgressFlag.RUnlock()
5225}
5226
5227// GetDeletionInProgress - TODO: add comment
5228func (dh *deviceHandler) GetDeletionInProgress() bool {
5229 return dh.deletionInProgress
5230}
5231
5232// GetPmConfigs - TODO: add comment
5233func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5234 return dh.pmConfigs
5235}
5236
5237// GetDeviceType - TODO: add comment
5238func (dh *deviceHandler) GetDeviceType() string {
5239 return dh.DeviceType
5240}
5241
5242// GetLogicalDeviceID - TODO: add comment
5243func (dh *deviceHandler) GetLogicalDeviceID() string {
5244 return dh.logicalDeviceID
5245}
5246
5247// GetDevice - TODO: add comment
5248func (dh *deviceHandler) GetDevice() *voltha.Device {
5249 return dh.device
5250}
5251
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005252func (dh *deviceHandler) setOltAvailable(value bool) {
5253 dh.mutexOltAvailable.Lock()
5254 dh.oltAvailable = value
5255 dh.mutexOltAvailable.Unlock()
5256}
5257
5258// IsOltAvailable - TODO: add comment
5259func (dh *deviceHandler) IsOltAvailable() bool {
5260 dh.mutexOltAvailable.RLock()
5261 defer dh.mutexOltAvailable.RUnlock()
5262 return dh.oltAvailable
5263}
5264
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005265// GetMetricsEnabled - TODO: add comment
5266func (dh *deviceHandler) GetMetricsEnabled() bool {
5267 return dh.pOpenOnuAc.MetricsEnabled
5268}
5269
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005270// GetExtendedOmciSupportEnabled - TODO: add comment
5271func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5272 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5273}
5274
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305275// GetExtendedOmciSupportEnabled - TODO: add comment
5276func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5277 return dh.pOpenOnuAc.skipOnuConfig
5278}
5279
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305280func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5281 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5282}
5283
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005284// InitPmConfigs - TODO: add comment
5285func (dh *deviceHandler) InitPmConfigs() {
5286 dh.pmConfigs = &voltha.PmConfigs{}
5287}
5288
5289// GetUniPortMask - TODO: add comment
5290func (dh *deviceHandler) GetUniPortMask() int {
5291 return dh.pOpenOnuAc.config.UniPortMask
5292}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005293
5294func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5295 tpPathFound := false
5296 for _, tpPath := range aTpPathMap {
5297 if tpPath != "" {
5298 tpPathFound = true
5299 }
5300 }
5301 return tpPathFound
5302}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005303
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305304func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5305 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5306 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5307 return resp
5308}
5309
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305310// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5311func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5312 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305313 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5314 return resp
5315}
5316
5317// getOnuFECStats - Get the GEM PM history data of the request ONT device
5318func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5319 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5320 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 +05305321 return resp
5322}
5323
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305324func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5325 return dh.deviceDeleteCommChan
5326}
5327
bseeniva71b1b662026-02-12 19:07:50 +05305328func (dh *deviceHandler) processOnuIndication(ctx context.Context, onuInd *ia.OnuIndicationMessage) (*emptypb.Empty, error) {
bseeniva0c06c862026-02-03 14:04:35 +05305329
5330 onuIndication := onuInd.OnuIndication
5331 onuOperstate := onuIndication.GetOperState()
5332
5333 if dh.GetDeletionInProgress() {
5334 logger.Warnw(ctx, "device deletion in progress, ignoring the ONU Indication", log.Fields{"device-id": dh.DeviceID})
5335 return nil, fmt.Errorf("device deletion in progress for device-id: %s", dh.DeviceID)
5336 }
5337
5338 logger.Infow(ctx, "onu-ind-request", log.Fields{"device-id": dh.DeviceID,
5339 "OnuId": onuIndication.GetOnuId(),
5340 "AdminState": onuIndication.GetAdminState(), "OperState": onuOperstate,
5341 "SNR": onuIndication.GetSerialNumber()})
5342
5343 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
5344 if pDevEntry == nil {
5345 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
5346 return nil, fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
5347 }
5348
5349 var event string
5350
5351 switch onuOperstate {
5352 case "up":
5353 if dh.pDeviceStateFsm.Current() == devStUp {
5354 logger.Errorw(ctx, "invalid state transition", log.Fields{"expectedState": devStDown, "currentState": dh.pDeviceStateFsm.Current()})
5355 return nil, fmt.Errorf("invalid state transition: expected %s, got %s", devStDown, dh.pDeviceStateFsm.Current())
5356 }
5357 event = devEvDeviceUpInd
5358 case "down", "unreachable":
5359 if dh.pDeviceStateFsm.Current() == devStDown {
5360 logger.Errorw(ctx, "invalid state transition", log.Fields{"expectedState": devStUp, "currentState": dh.pDeviceStateFsm.Current()})
5361 return nil, fmt.Errorf("invalid state transition: expected %s, got %s", devStUp, dh.pDeviceStateFsm.Current())
5362 }
5363 event = devEvDeviceDownInd
5364 default:
5365 logger.Errorw(ctx, "unknown-onu-ind-request operState", log.Fields{"OnuId": onuIndication.GetOnuId()})
5366 return nil, fmt.Errorf("invalidOperState: %s, %s", onuOperstate, dh.DeviceID)
5367 }
5368
5369 err := dh.pDeviceStateFsm.Event(event, onuIndication)
5370 if err != nil {
5371 return nil, err
5372 }
5373
bseeniva71b1b662026-02-12 19:07:50 +05305374 return &emptypb.Empty{}, nil
bseeniva0c06c862026-02-03 14:04:35 +05305375}
5376
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005377// PrepareForGarbageCollection - remove references to prepare for garbage collection
5378func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5379 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5380
5381 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5382 // first let the objects rest for some time to give all asynchronously started
5383 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005384 time.Sleep(2 * time.Second)
5385
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005386 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005387
5388 if dh.pOnuTP != nil {
5389 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5390 }
5391 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005392 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5393 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005394 select {
5395 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5396 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5397 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5398 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005399 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005400 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005401 }
5402 if dh.pAlarmMgr != nil {
5403 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5404 }
5405 if dh.pSelfTestHdlr != nil {
5406 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5407 }
5408 if dh.pLockStateFsm != nil {
5409 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5410 }
5411 if dh.pUnlockStateFsm != nil {
5412 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5413 }
5414 if dh.pOnuUpradeFsm != nil {
5415 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5416 }
5417 if dh.pOnuOmciDevice != nil {
5418 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5419 }
5420 for k, v := range dh.UniVlanConfigFsmMap {
5421 v.PrepareForGarbageCollection(ctx, aDeviceID)
5422 delete(dh.UniVlanConfigFsmMap, k)
5423 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305424 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005425 dh.pOnuOmciDevice = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305426 dh.lockDevice.Lock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005427 dh.pOnuTP = nil
bseeniva0cbc62a2026-01-23 19:08:36 +05305428 dh.lockDevice.Unlock()
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005429 dh.pOnuMetricsMgr = nil
5430 dh.pAlarmMgr = nil
5431 dh.pSelfTestHdlr = nil
5432 dh.pLockStateFsm = nil
5433 dh.pUnlockStateFsm = nil
5434 dh.pOnuUpradeFsm = nil
5435}