blob: a3cdb6c5873d217473f020940060a64cdb25c998 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040049 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040050 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000051 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040052 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000056 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040057 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000058 "google.golang.org/grpc/codes"
59 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060)
61
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062const (
mpagenko101ac942021-11-16 15:01:29 +000063 //constants for reconcile flow check channel
64 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
65 cWaitReconcileFlowAbortOnError = 0xFFFE
66 cWaitReconcileFlowNoActivity = 0xFFFF
67)
68
69const (
70 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000071 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000072)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000073
mpagenko1cc3cb42020-07-27 15:24:38 +000074const (
mpagenko44bd8362021-11-15 11:40:05 +000075 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
76 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
77 // as long as such is not available by the libraries - use this workaround
78 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
79)
80
81const (
mpagenko1cc3cb42020-07-27 15:24:38 +000082 // events of Device FSM
83 devEvDeviceInit = "devEvDeviceInit"
84 devEvGrpcConnected = "devEvGrpcConnected"
85 devEvGrpcDisconnected = "devEvGrpcDisconnected"
86 devEvDeviceUpInd = "devEvDeviceUpInd"
87 devEvDeviceDownInd = "devEvDeviceDownInd"
88)
89const (
90 // states of Device FSM
91 devStNull = "devStNull"
92 devStDown = "devStDown"
93 devStInit = "devStInit"
94 devStConnected = "devStConnected"
95 devStUp = "devStUp"
96)
97
praneeth nalmas5a0a5502022-12-23 15:57:00 +053098// 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 +000099const (
Himani Chawla4d908332020-08-31 12:30:20 +0530100 pon = voltha.EventSubCategory_PON
101 //olt = voltha.EventSubCategory_OLT
102 //ont = voltha.EventSubCategory_ONT
103 //onu = voltha.EventSubCategory_ONU
104 //nni = voltha.EventSubCategory_NNI
105 //service = voltha.EventCategory_SERVICE
106 //security = voltha.EventCategory_SECURITY
107 equipment = voltha.EventCategory_EQUIPMENT
108 //processing = voltha.EventCategory_PROCESSING
109 //environment = voltha.EventCategory_ENVIRONMENT
110 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000111)
112
113const (
114 cEventObjectType = "ONU"
115)
116const (
117 cOnuActivatedEvent = "ONU_ACTIVATED"
118)
119
mpagenkof1fc3862021-02-16 10:09:52 +0000120type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000122 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
126 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
127 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
128 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
129 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
130 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
131 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
132 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
133 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000134}
135
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000136const (
137 cNoReconciling = iota
138 cOnuConfigReconciling
139 cSkipOnuConfigReconciling
140)
141
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142// FlowCb is the flow control block containing flow add/delete information along with a response channel
143type FlowCb struct {
144 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 flowItem *of.OfpFlowStats
146 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400147 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700148 respChan *chan error // channel to report the Flow handling error
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530149 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700150}
151
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530152// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530154 EventProxy eventif.EventProxy
155
156 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157
khenaidoo7d3c5582021-08-11 18:09:44 -0400158 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000159
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800160 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400161 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800162
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163 pOpenOnuAc *OpenONUAC
164 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530165 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530166 deviceEntrySet chan bool //channel for DeviceEntry set event
167 pOnuOmciDevice *mib.OnuDeviceEntry
168 pOnuTP *avcfg.OnuUniTechProf
169 pOnuMetricsMgr *pmmgr.OnuMetricsManager
170 pAlarmMgr *almgr.OnuAlarmManager
171 pSelfTestHdlr *otst.SelfTestControlBlock
172 exitChannel chan int
173 pOnuIndication *oop.OnuIndication
174 pLockStateFsm *uniprt.LockStateFsm
175 pUnlockStateFsm *uniprt.LockStateFsm
176
177 stopCollector chan bool
178 stopAlarmManager chan bool
179 stopHeartbeatCheck chan bool
180 uniEntityMap cmn.OnuUniPortMap
181 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
182 pOnuUpradeFsm *swupg.OnuUpgradeFsm
183 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530184 chUniVlanConfigOnRebootDone chan uint16
185 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530186 pLastUpgradeImageState *voltha.ImageState
187 upgradeFsmChan chan struct{}
188
189 deviceDeleteCommChan chan bool
190 DeviceID string
191 DeviceType string
192 adminState string
193 logicalDeviceID string
194 ProxyAddressID string
195 ProxyAddressType string
196 parentID string
197
198 flowCbChan []chan FlowCb
199 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
200 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
201 reconcileExpiryComplete time.Duration
202 reconcileExpiryVlanConfig time.Duration
203 lockDevice sync.RWMutex
204 mutexDeviceReason sync.RWMutex
205 mutexCollectorFlag sync.RWMutex
206 mutextAlarmManagerFlag sync.RWMutex
207 lockVlanConfig sync.RWMutex
208 lockVlanAdd sync.RWMutex
209 lockUpgradeFsm sync.RWMutex
210 mutexReconcilingFlag sync.RWMutex
211 mutexReconcilingFirstPassFlag sync.RWMutex
212 mutexReconcilingReasonUpdate sync.RWMutex
213 mutexReadyForOmciConfig sync.RWMutex
214 mutexDeletionInProgressFlag sync.RWMutex
215 mutexFlowMonitoringRoutineFlag sync.RWMutex
216 mutexForDisableDeviceRequested sync.RWMutex
217 mutexOltAvailable sync.RWMutex
218 mutexKvStoreContext sync.Mutex
219 ponPortNumber uint32
220
221 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000223 //flowMgr *OpenOltFlowMgr
224 //eventMgr *OpenOltEventMgr
225 //resourceMgr *rsrcMgr.OpenOltResourceMgr
226
227 //discOnus sync.Map
228 //onus sync.Map
229 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530230 collectorIsRunning bool
231 alarmManagerIsRunning bool
232 upgradeCanceled bool
233 reconciling uint8
234 reconcilingFirstPass bool
235 reconcilingReasonUpdate bool
236 readyForOmciConfig bool
237 deletionInProgress bool
238 disableDeviceRequested bool // this flag identify ONU received disable request or not
239 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240}
241
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530242// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400243func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530244 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400245 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000246 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400247 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000249 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000250 dh.DeviceType = cloned.Type
251 dh.adminState = "up"
252 dh.device = cloned
253 dh.pOpenOnuAc = adapter
254 dh.exitChannel = make(chan int, 1)
255 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000256 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000257 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530259 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530260 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 dh.stopHeartbeatCheck = make(chan bool, 2)
262 //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 +0000263 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000264 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000265 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000266 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000267 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300268 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000269 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000270 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000271 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000272 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300273 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000274 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000275 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000276 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
277 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
278 if rECSeconds < 2 {
279 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
280 rECSeconds = 2
281 }
282 rEVCSeconds := rECSeconds / 2
283 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000284 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000285 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000286 dh.pLastUpgradeImageState = &voltha.ImageState{
287 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
288 Reason: voltha.ImageState_UNKNOWN_ERROR,
289 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
290 }
291 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530292 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800294 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
295 dh.pmConfigs = cloned.PmConfigs
296 } /* else {
297 // will be populated when onu_metrics_mananger is initialized.
298 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800299
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 // Device related state machine
301 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000302 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000304 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
305 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
306 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
307 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
308 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309 },
310 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
312 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
313 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
314 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
315 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
316 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
317 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
318 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 },
320 )
mpagenkoaf801632020-07-03 10:00:42 +0000321
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322 return &dh
323}
324
Himani Chawla6d2ae152020-09-02 13:11:20 +0530325// start save the device to the data model
326func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000327 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000329 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330}
331
Himani Chawla4d908332020-08-31 12:30:20 +0530332/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000333// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530334func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335 logger.Debug("stopping-device-handler")
336 dh.exitChannel <- 1
337}
Himani Chawla4d908332020-08-31 12:30:20 +0530338*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
340// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530341// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000342
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530343// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530344func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400345 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000346
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000347 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530348
mpagenko1cc3cb42020-07-27 15:24:38 +0000349 if dh.pDeviceStateFsm.Is(devStNull) {
350 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000351 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 +0000352 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000353 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800354 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
355 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800356 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400357 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800359 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800360 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000361 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000363 }
364
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000365}
366
khenaidoo42dcdfd2021-10-19 17:34:12 -0400367func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000368 /* 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 +0530369 //assuming omci message content is hex coded!
370 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000372 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000373 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000376 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000377 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000378 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000379 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
380 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
383 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530384}
385
khenaidoo42dcdfd2021-10-19 17:34:12 -0400386func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000388
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000389 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
392 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 if dh.pOnuTP == nil {
395 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000396 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000397 log.Fields{"device-id": dh.DeviceID})
398 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000400 if !dh.IsReadyForOmciConfig() {
401 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
402 "device-state": dh.GetDeviceReasonString()})
403 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000405 //previous state test here was just this one, now extended for more states to reject the SetRequest:
406 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
407 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530408
Himani Chawla26e555c2020-08-31 12:30:20 +0530409 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
411 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 dh.pOnuTP.LockTpProcMutex()
413 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000414
mpagenko44bd8362021-11-15 11:40:05 +0000415 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530416 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
417 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000418 }
419 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000420 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000422 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
423 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800424 return err
425 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000426 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
427 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000429 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530430
Girish Gowdra50e56422021-06-01 16:46:04 -0700431 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400432 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000433 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
434 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000435
436 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
437 if err != nil {
438 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
439 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
440 // stopping all further processing
441 _ = dh.UpdateInterface(ctx)
442 return err
443 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700444 // if there has been some change for some uni TechProfilePath
445 //in order to allow concurrent calls to other dh instances we do not wait for execution here
446 //but doing so we can not indicate problems to the caller (who does what with that then?)
447 //by now we just assume straightforward successful execution
448 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
449 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530450
Girish Gowdra50e56422021-06-01 16:46:04 -0700451 // deadline context to ensure completion of background routines waited for
452 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
453 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
454 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000455
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700457
458 var wg sync.WaitGroup
459 wg.Add(1) // for the 1 go routine to finish
460 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
464 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 -0700465 return tpErr
466 }
467 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
468 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530469 defer cancel2()
470 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
471 if err1 != nil {
472 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
473 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700474 }
475 return nil
476 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000477 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700478 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000482 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
483 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 return nil
485}
486
khenaidoo42dcdfd2021-10-19 17:34:12 -0400487func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000488 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530489
490 if dh.pOnuTP == nil {
491 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 log.Fields{"device-id": dh.DeviceID})
494 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530496 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 dh.pOnuTP.LockTpProcMutex()
498 defer dh.pOnuTP.UnlockTpProcMutex()
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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000525 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
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 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 if dh.pOnuTP == nil {
531 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000532 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 log.Fields{"device-id": dh.DeviceID})
534 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530535 }
536
Himani Chawla26e555c2020-08-31 12:30:20 +0530537 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538 dh.pOnuTP.LockTpProcMutex()
539 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540
mpagenko0f543222021-11-03 16:24:14 +0000541 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
542 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
543 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530544 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
545 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000546 }
547 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700548 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800550 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000551 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
552 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800553 return err
554 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530556
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000557 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
558 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530559 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000560 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 +0530561 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
562 if err1 != nil {
563 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
564 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000565 }
566
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000569
Mahir Gunyel9545be22021-07-04 15:53:16 -0700570}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000571
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
574 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
577 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530578 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700579 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700581 resourceName = "Gem"
582 } else {
583 resourceName = "Tcont"
584 }
585
586 // deadline context to ensure completion of background routines waited for
587 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
588 dctx, cancel := context.WithDeadline(context.Background(), deadline)
589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700591
592 var wg sync.WaitGroup
593 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700595 resource, entryID, &wg)
596 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
598 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700599 return err
600 }
601
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
603 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
604 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
605 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700606 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530607 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700608 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000609 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 +0530610 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
611 if err != nil {
612 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700613 return err
614 }
615 }
616 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700618 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530619 return nil
620}
621
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530622// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400624 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400625 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
627 var errorsList []error
628 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530629 if dh.GetPersRebootFlag(ctx) {
630 logger.Warnw(ctx, "FlowUpdateIncremental ignored as deivce is being configured post reboot", log.Fields{"device-id": dh.DeviceID})
631 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
632 }
mpagenko01e726e2020-10-23 09:45:29 +0000633 //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 +0000634 if apOfFlowChanges.ToRemove != nil {
635 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000636 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000637 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 "device-id": dh.DeviceID})
639 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700640 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000641 continue
642 }
643 flowInPort := flow.GetInPort(flowItem)
644 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
646 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700647 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000648 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000650 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000651 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000654 continue
655 } else {
656 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000658 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
659 loUniPort = uniPort
660 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000661 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000662 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000663 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000666 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000667 }
668 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000670 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
671 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672
673 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
674 // Step1 : Fill flowControlBlock
675 // Step2 : Push the flowControlBlock to ONU channel
676 // Step3 : Wait on response channel for response
677 // Step4 : Return error value
678 startTime := time.Now()
679 respChan := make(chan error)
680 flowCb := FlowCb{
681 ctx: ctx,
682 addFlow: false,
683 flowItem: flowItem,
684 flowMetaData: nil,
685 uniPort: loUniPort,
686 respChan: &respChan,
687 }
688 dh.flowCbChan[loUniPort.UniID] <- flowCb
689 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
690 // Wait on the channel for flow handlers return value
691 retError = <-respChan
692 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
693 if retError != nil {
694 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
695 log.Fields{"device-id": dh.DeviceID, "error": retError})
696 errorsList = append(errorsList, retError)
697 continue
698 }
699 } else {
700 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
701 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000702 }
703 }
704 }
705 }
mpagenko01e726e2020-10-23 09:45:29 +0000706 if apOfFlowChanges.ToAdd != nil {
707 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
708 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 "device-id": dh.DeviceID})
711 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700712 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000713 continue
714 }
715 flowInPort := flow.GetInPort(flowItem)
716 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000717 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
718 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700719 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000720 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000721 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000722 } else if flowInPort == dh.ponPortNumber {
723 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000726 continue
727 } else {
728 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000730 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
731 loUniPort = uniPort
732 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000733 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000734 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000735 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700737 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000738 continue
mpagenko01e726e2020-10-23 09:45:29 +0000739 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000740 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
741 // if not, we just throw some error here to have an indication about that, if we really need to support that
742 // then we would need to create some means to activate the internal stored flows
743 // after the device gets active automatically (and still with its dependency to the TechProfile)
744 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
745 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000746 if !dh.IsReadyForOmciConfig() {
747 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
748 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700749 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
750 errorsList = append(errorsList, retError)
751 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000752 }
753
mpagenko01e726e2020-10-23 09:45:29 +0000754 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
757 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700758 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
759 // Step1 : Fill flowControlBlock
760 // Step2 : Push the flowControlBlock to ONU channel
761 // Step3 : Wait on response channel for response
762 // Step4 : Return error value
763 startTime := time.Now()
764 respChan := make(chan error)
765 flowCb := FlowCb{
766 ctx: ctx,
767 addFlow: true,
768 flowItem: flowItem,
769 flowMetaData: apFlowMetaData,
770 uniPort: loUniPort,
771 respChan: &respChan,
772 }
773 dh.flowCbChan[loUniPort.UniID] <- flowCb
774 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
775 // Wait on the channel for flow handlers return value
776 retError = <-respChan
777 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
778 if retError != nil {
779 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
780 log.Fields{"device-id": dh.DeviceID, "error": retError})
781 errorsList = append(errorsList, retError)
782 continue
783 }
784 } else {
785 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
786 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000787 }
788 }
789 }
790 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700791 if len(errorsList) > 0 {
792 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
793 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
794 }
795 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000796}
797
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530798// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
799// following are the expected device states after this activity:
800// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000801// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
803 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300804 dh.mutexForDisableDeviceRequested.Lock()
805 dh.disableDeviceRequested = true
806 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000807 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000808 //note that disableDevice sequences in some 'ONU active' state may yield also
809 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000810 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000811 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000812 //disable-device shall be just a UNi/ONU-G related admin state setting
813 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000814
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000816 // disable UNI ports/ONU
817 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
818 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000819 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000820 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000823 }
824 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000825 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000827 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400828 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000830 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400831 OperStatus: voltha.OperStatus_UNKNOWN,
832 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000833 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000834 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000835 }
mpagenko01e726e2020-10-23 09:45:29 +0000836 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000837
838 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000839 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000840 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300841 }
842}
843
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530844// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
846 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000847
mpagenkoaa3afe92021-05-21 16:20:58 +0000848 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000849 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
850 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
851 // for real ONU's that should have nearly no influence
852 // Note that for real ONU's there is anyway a problematic situation with following sequence:
853 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
854 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
855 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000857
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000858 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300860 dh.mutexForDisableDeviceRequested.Lock()
861 dh.disableDeviceRequested = false
862 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000863 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000864 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000865 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000867 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000868 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300869}
870
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530872 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000873
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 return
878 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000880 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000881 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000882 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000884 }
mpagenko101ac942021-11-16 15:01:29 +0000885 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000886 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000887 }
Himani Chawla4d908332020-08-31 12:30:20 +0530888 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 pDevEntry.MutexPersOnuConfig.RLock()
890 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
891 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
892 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
893 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
894 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000896}
897
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000898func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530899 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000900
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000901 continueWithFlowConfig := false
902
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000904 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000905 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000906 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
907 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000908 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 dh.pOnuTP.LockTpProcMutex()
910 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000911
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000913 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
915 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530916 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000917 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000918 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
919 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000920 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000921 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700922 techProfsFound := false
923 techProfInstLoadFailed := false
924outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000926 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000928 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000929 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000930 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000931 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000932 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
934 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000935 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000936 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000937 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700938 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000939 var iaTechTpInst ia.TechProfileDownloadMessage
940 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800941 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000942 pDevEntry.MutexReconciledTpInstances.RLock()
943 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
944 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000945 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000946 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000948 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700949 break outerLoop
950 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000951 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000952 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 var tpInst tech_profile.TechProfileInstance
954 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400955 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000957 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700959 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000960 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000961 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700962 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
963 break outerLoop
964 }
965
Girish Gowdra041dcb32020-11-16 16:54:30 -0800966 // deadline context to ensure completion of background routines waited for
967 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
968 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800972 var wg sync.WaitGroup
973 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000974 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000975 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
977 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700978 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
979 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800980 }
mpagenko2dc896e2021-08-02 12:03:59 +0000981 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 if len(uniData.PersFlowParams) != 0 {
983 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000984 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000985 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000986 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000987 } // for all UNI entries from SOnuPersistentData
988 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
989 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000990 }
mpagenko2dc896e2021-08-02 12:03:59 +0000991
992 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
993 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000994
995 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000996}
997
998func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
999 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1000 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301001 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001003 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001004 return
1005 }
mpagenko2dc896e2021-08-02 12:03:59 +00001006 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001007 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001008 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001009 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001011 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 }
mpagenko2dc896e2021-08-02 12:03:59 +00001013 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301014 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001016 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001017 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018}
1019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1021 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001022
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001024 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001025 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001026 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001027 return
1028 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001029
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001030 pDevEntry.MutexPersOnuConfig.RLock()
1031 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1032 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301033 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001034 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001035 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001036 return
1037 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001038 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001039 var uniVlanConfigEntries []uint8
1040 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1041
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001043 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1044 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001045 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001047 continue
1048 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001049 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001050 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001052 // It doesn't make sense to configure any flows if no TPs are available
1053 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001054 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1056 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001057 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001058 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001059
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001060 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001062 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001064 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1065 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001066 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001067 return
1068 }
mpagenko101ac942021-11-16 15:01:29 +00001069 //needed to split up function due to sca complexity
1070 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1071
mpagenko2dc896e2021-08-02 12:03:59 +00001072 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001073 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1075 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001076 // this can't be used as global finished reconciling flag because
1077 // assumes is getting called before the state machines for the last flow is completed,
1078 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1080 } // for all UNI entries from SOnuPersistentData
1081 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001082
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001083 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301084 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001085 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001086 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001087 return
1088 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001089 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1090 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1091 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1092 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1093 log.Fields{"device-id": dh.DeviceID})
1094 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1095 if pDevEntry != nil {
1096 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001097 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001098 } else {
1099 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1100 log.Fields{"device-id": dh.DeviceID})
1101 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1102 if pDevEntry != nil {
1103 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1104 }
1105 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001106 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001107 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001108}
1109
mpagenko101ac942021-11-16 15:01:29 +00001110func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1111 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1112 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1113 flowsProcessed := 0
1114 lastFlowToReconcile := false
1115 loUniID := apUniPort.UniID
1116 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001117 if !(*apFlowsFound) {
1118 *apFlowsFound = true
1119 syncChannel := make(chan struct{})
1120 // start go routine with select() on reconciling vlan config channel before
1121 // starting vlan config reconciling process to prevent loss of any signal
1122 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1123 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1124 //block until the wait routine is really blocked on channel input
1125 // in order to prevent to early ready signal from VlanConfig processing
1126 <-syncChannel
1127 }
1128 if flowsProcessed == len(aPersFlowParam)-1 {
1129 var uniAdded bool
1130 lastFlowToReconcile = true
1131 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1132 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001133 }
1134 }
mpagenko101ac942021-11-16 15:01:29 +00001135 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1136 "device-id": dh.DeviceID, "uni-id": loUniID,
1137 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1138 dh.lockVlanConfig.Lock()
1139 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1140 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1141 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301142 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 +00001143 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1144 }
1145 } else {
1146 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301147 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301148 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001149 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1150 }
1151 }
1152 dh.lockVlanConfig.Unlock()
1153 flowsProcessed++
1154 } //for all flows of this UNI
1155}
1156
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301157// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1158//
1159// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001160func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1161 waitGroup *cmn.WaitGroupWithTimeOut) {
1162 var reconciledUniVlanConfigEntries []uint8
1163 var appended bool
1164 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1165 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1166 "device-id": dh.DeviceID, "expiry": expiry})
1167 // indicate blocking on channel now to the caller
1168 aSyncChannel <- struct{}{}
1169 for {
1170 select {
1171 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1172 switch uniIndication {
1173 // no activity requested (should normally not be received) - just continue waiting
1174 case cWaitReconcileFlowNoActivity:
1175 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1176 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301177 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001178 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1179 return
1180 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1181 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301182 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001183 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1184 return
1185 // this should be a valid UNI vlan config done indication
1186 default:
1187 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301188 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001189 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1190 if reconciledUniVlanConfigEntries, appended =
1191 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1192 waitGroup.Done()
1193 }
1194 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301195 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 +00001196 }
1197 } //switch uniIndication
1198
1199 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1200 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1201 log.Fields{"device-id": dh.DeviceID})
1202 return
1203 }
1204 }
1205}
1206
1207func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1208 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1209}
1210
1211func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1212 for _, ele := range slice {
1213 if ele == val {
1214 return slice, false
1215 }
1216 }
1217 return append(slice, val), true
1218}
1219
1220// sendChReconcileFinished - sends true or false on reconcileFinish channel
1221func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1222 if dh != nil { //if the object still exists (might have been already deleted in background)
1223 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1224 select {
1225 case dh.chReconcilingFinished <- success:
1226 default:
1227 }
1228 }
1229}
1230
1231// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1232func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1233 if dh != nil { //if the object still exists (might have been already deleted in background)
1234 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1235 select {
1236 case dh.chUniVlanConfigReconcilingDone <- value:
1237 default:
1238 }
1239 }
1240}
1241
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301242func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1243 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1244
1245 defer dh.UpdateAndStoreRebootState(ctx, false)
1246 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1247 if pDevEntry == nil {
1248 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1249 return
1250 }
1251
1252 pDevEntry.MutexPersOnuConfig.RLock()
1253 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1254 pDevEntry.MutexPersOnuConfig.RUnlock()
1255 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1256 log.Fields{"device-id": dh.DeviceID})
1257 return
1258 }
1259 flowsFound := false
1260 var uniVlanConfigEntries []uint8
1261 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1262
1263 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1264 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1265 if len(uniData.PersFlowParams) == 0 {
1266 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1267 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1268 continue
1269 }
1270 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1271 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1272 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1273 // It doesn't make sense to configure any flows if no TPs are available
1274 continue
1275 }
1276 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1277 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1278 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1279 pDevEntry.MutexPersOnuConfig.RUnlock()
1280
1281 var uniPort *cmn.OnuUniPort
1282 var exist bool
1283 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1284 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1285 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1286 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1287 return
1288 }
1289
1290 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1291
1292 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1293 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1294 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1295 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1296 // this can't be used as global finished reconciling flag because
1297 // assumes is getting called before the state machines for the last flow is completed,
1298 // while this is not guaranteed.
1299 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1300 } // for all UNI entries from SOnuPersistentData
1301 pDevEntry.MutexPersOnuConfig.RUnlock()
1302
1303 if !flowsFound {
1304 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1305 log.Fields{"device-id": dh.DeviceID})
1306 return
1307 }
1308 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1309 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1310 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1311 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1312 log.Fields{"device-id": dh.DeviceID})
1313 } else {
1314 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1315 log.Fields{"device-id": dh.DeviceID})
1316 return
1317 }
1318}
1319
1320func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1321 dh.UpdateRebootPersData(ctx, flag)
1322 if err := dh.StorePersistentData(ctx); err != nil {
1323 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1324 }
1325}
1326
1327func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1328 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1329 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1330 flowsProcessed := 0
1331 lastFlowToConfigOnReboot := false
1332 loUniID := apUniPort.UniID
1333 for _, flowData := range aPersFlowParam {
1334 if !(*apFlowsFound) {
1335 *apFlowsFound = true
1336 syncChannel := make(chan struct{})
1337 // start go routine with select() on reconciling vlan config channel before
1338 // starting vlan config reconciling process to prevent loss of any signal
1339 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1340 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1341 //block until the wait routine is really blocked on channel input
1342 // in order to prevent to early ready signal from VlanConfig processing
1343 <-syncChannel
1344 }
1345 if flowsProcessed == len(aPersFlowParam)-1 {
1346 var uniAdded bool
1347 lastFlowToConfigOnReboot = true
1348 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1349 apWaitGroup.Add(1) //increment the waiting group
1350 }
1351 }
1352 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1353 "device-id": dh.DeviceID, "uni-id": loUniID,
1354 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1355 dh.lockVlanConfig.Lock()
1356 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1357 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1358 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1359 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 {
1360 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1361 }
1362 } else {
1363 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1364 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1365 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1366 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1367 }
1368 }
1369 dh.lockVlanConfig.Unlock()
1370 flowsProcessed++
1371 } //for all flows of this UNI
1372}
1373
1374func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1375 waitGroup *cmn.WaitGroupWithTimeOut) {
1376 var rebootUniVlanConfigEntries []uint8
1377 var appended bool
1378 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1379 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1380 "device-id": dh.DeviceID, "expiry": expiry})
1381 // indicate blocking on channel now to the caller
1382 aSyncChannel <- struct{}{}
1383 for {
1384 select {
1385 case <-dh.deviceDeleteCommChan:
1386 // Cancel the context and return
1387 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1388 return
1389
1390 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1391 switch uniIndication {
1392 // this should be a valid UNI vlan config done indication
1393 default:
1394 if uniIndication < platform.MaxUnisPerOnu {
1395 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1396 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1397 if rebootUniVlanConfigEntries, appended =
1398 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1399 waitGroup.Done()
1400 }
1401 } else {
1402 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1403 }
1404 } //switch uniIndication
1405
1406 case <-time.After(expiry):
1407 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1408 log.Fields{"device-id": dh.DeviceID})
1409 return
1410 }
1411 }
1412}
1413
1414func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1415 if dh != nil { //if the object still exists (might have been already deleted in background)
1416 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1417 select {
1418 case dh.chUniVlanConfigOnRebootDone <- value:
1419 default:
1420 }
1421 }
1422}
1423
1424func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
1425 logger.Info(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
1426 techProfInstLoadFailed := false
1427 continueWithFlowConfig := false
1428 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1429 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1430 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1431
1432 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1433 if pDevEntry == nil {
1434 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1435 return continueWithFlowConfig
1436 }
1437 dh.lockDevice.RLock()
1438 if dh.pOnuTP == nil {
1439 //should normally not happen ...
1440 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1441 log.Fields{"device-id": dh.DeviceID})
1442 dh.lockDevice.RUnlock()
1443 return continueWithFlowConfig
1444 }
1445
1446 dh.pOnuTP.LockTpProcMutex()
1447 defer dh.pOnuTP.UnlockTpProcMutex()
1448 defer dh.lockDevice.RUnlock()
1449
1450 pDevEntry.MutexPersOnuConfig.RLock()
1451 persMutexLock := true
1452 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1453 pDevEntry.MutexPersOnuConfig.RUnlock()
1454 logger.Info(ctx, "no uni-configs have been stored - aborting",
1455 log.Fields{"device-id": dh.DeviceID})
1456 return continueWithFlowConfig
1457 }
1458
1459outerLoop:
1460 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1461 uniID := uniData.PersUniID
1462
1463 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1464 logger.Debugw(ctx, "no TPs stored for uniID",
1465 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1466 continue
1467 }
1468 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1469 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1470 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1471 pDevEntry.MutexPersOnuConfig.RUnlock()
1472 persMutexLock = false
1473 for tpID, tpPath := range uniData.PersTpPathMap {
1474 if tpPath != "" {
1475 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1476 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1477 })
1478 // Attempt the initial call before entering the retry loop
1479 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1480 if err != nil {
1481 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1482 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1483 })
1484 techProfInstLoadFailed = true
1485 break outerLoop
1486 }
1487 if iaTechTpInst != nil {
1488 var tpInst tech_profile.TechProfileInstance
1489 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1490 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1491 tpInst = *techTpInst.TpInstance
1492 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1493 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1494 default: // do not support epon or other tech
1495 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1496 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1497 techProfInstLoadFailed = true
1498 break outerLoop
1499 }
1500
1501 continueWithFlowConfig = true
1502 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1503 dctx, cancel := context.WithDeadline(ctx, deadline)
1504
1505 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1506 var wg sync.WaitGroup
1507 wg.Add(1) // for the 1 go routine to finish
1508 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1509 // Wait for either completion or cancellation
1510 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1511 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1512 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1513 techProfInstLoadFailed = true
1514 continueWithFlowConfig = false
1515 break outerLoop
1516 }
1517 } else {
1518 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1519 techProfInstLoadFailed = true
1520 break outerLoop
1521 }
1522 } else {
1523 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1524 "uni-id": uniID, "device-id": dh.DeviceID})
1525 techProfInstLoadFailed = true
1526 break outerLoop
1527 }
1528 }
1529 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1530 persMutexLock = true
1531 }
1532 if persMutexLock {
1533 pDevEntry.MutexPersOnuConfig.RUnlock()
1534 }
1535 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1536 return continueWithFlowConfig
1537}
1538
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001540 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001541
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001543 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001544 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001546 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001547 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001548
1549 // deadline context to ensure completion of background routines waited for
1550 //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 +05301551 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301553 defer cancel()
1554 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1555 if err != nil {
1556 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1557 return err
1558 }
1559 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001560}
1561
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301562// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001563// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301564//
1565// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1566//
1567// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001568func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001569 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001570 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001572 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001573 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301575 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001576 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001577 return
Himani Chawla4d908332020-08-31 12:30:20 +05301578 }
mpagenko01e726e2020-10-23 09:45:29 +00001579
1580 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001581 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001582
mpagenko44bd8362021-11-15 11:40:05 +00001583 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001585 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001586 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001587 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001588 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001589 OperStatus: voltha.OperStatus_DISCOVERED,
1590 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001591 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001592 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001593 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001594 }
mpagenkoe4782082021-11-25 12:04:26 +00001595 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001596 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001597 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001598 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001599 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1600 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1601 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1602 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001603}
1604
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301605// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1606//
1607// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001608func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001610 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001611 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001612
1613 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001615 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001616 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1617 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001618 }
1619
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001621 var inactiveImageID uint16
1622 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1623 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001624 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1625 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001626 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001628 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001629 if err == nil {
1630 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1631 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001633 }
1634 } else {
1635 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001636 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001637 }
mpagenko15ff4a52021-03-02 10:09:20 +00001638 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001639 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001641 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1642 dh.upgradeCanceled = true
1643 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1644 }
mpagenko38662d02021-08-11 09:45:19 +00001645 //no effort spent anymore for the old API to automatically cancel and restart the download
1646 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001647 }
mpagenko15ff4a52021-03-02 10:09:20 +00001648 } else {
1649 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001650 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001651 }
1652 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1654 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001655 }
1656 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001657}
1658
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301659// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001660// after the OnuImage has been downloaded to the adapter, called in background
1661func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001663
1664 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001666 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001668 return
1669 }
1670
1671 var inactiveImageID uint16
1672 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1673 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001675
mpagenko59862f02021-10-11 08:53:18 +00001676 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001678 // but must be still locked at calling createOnuUpgradeFsm
1679 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1680 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1681 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001682 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1683 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001685 //flush the remove upgradeFsmChan channel
1686 select {
1687 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001688 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001689 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001690 }
mpagenko59862f02021-10-11 08:53:18 +00001691 dh.lockUpgradeFsm.Unlock()
1692 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1693 dh.upgradeCanceled = true
1694 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1695 }
mpagenko38662d02021-08-11 09:45:19 +00001696 select {
1697 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001698 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001699 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1700 return
1701 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001702 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001703 }
mpagenko59862f02021-10-11 08:53:18 +00001704 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001705 }
mpagenko38662d02021-08-11 09:45:19 +00001706
1707 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001708 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001709 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001710 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001711 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001712 if err == nil {
1713 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1714 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1715 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001716 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001717 return
1718 }
mpagenko38662d02021-08-11 09:45:19 +00001719 } else {
1720 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001721 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001722 }
1723 return
1724 }
1725 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001726 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001727}
1728
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301729// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001730func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1731 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001732 var err error
1733 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1734 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1735 // 2.) activation of the inactive image
1736
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001737 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001738 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001739 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1740 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001741 }
1742 dh.lockUpgradeFsm.RLock()
1743 if dh.pOnuUpradeFsm != nil {
1744 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001746 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001747 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1748 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001749 }
mpagenko59862f02021-10-11 08:53:18 +00001750 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1751 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1752 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1753 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001754 // use the OnuVendor identification from this device for the internal unique name
1755 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001756 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001757 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001758 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001759 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001760 "device-id": dh.DeviceID, "error": err})
1761 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001762 }
mpagenko183647c2021-06-08 15:25:04 +00001763 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001764 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001765 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001766 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001767 } //else
1768 dh.lockUpgradeFsm.RUnlock()
1769
1770 // 2.) check if requested image-version equals the inactive one and start its activation
1771 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1772 var inactiveImageID uint16
1773 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1774 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001775 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1776 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001777 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001778 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001779 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001780 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001781 if err == nil {
1782 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1783 inactiveImageID, aCommitRequest); err != nil {
1784 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 "device-id": dh.DeviceID, "error": err})
1786 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001787 }
1788 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001789 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001790 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001791 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001792 } //else
1793 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001794 "device-id": dh.DeviceID, "error": err})
1795 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001796}
1797
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301798// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001799func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1800 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001801 var err error
1802 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1803 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1804 // 2.) commitment of the active image
1805
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001806 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001807 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1809 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001810 }
1811 dh.lockUpgradeFsm.RLock()
1812 if dh.pOnuUpradeFsm != nil {
1813 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001814 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001815 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001816 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1817 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001818 }
mpagenko59862f02021-10-11 08:53:18 +00001819 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1820 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1821 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1822 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001823 // use the OnuVendor identification from this device for the internal unique name
1824 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001825 // 1.) check a started upgrade process and relay the commitment request to it
1826 // the running upgrade may be based either on the imageIdentifier (started from download)
1827 // or on the imageVersion (started from pure activation)
1828 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1829 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001830 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001831 "device-id": dh.DeviceID, "error": err})
1832 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001833 }
mpagenko183647c2021-06-08 15:25:04 +00001834 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001836 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001837 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001838 } //else
1839 dh.lockUpgradeFsm.RUnlock()
1840
mpagenko183647c2021-06-08 15:25:04 +00001841 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001842 var activeImageID uint16
1843 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1844 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001845 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1846 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001847 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001848 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001849 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001850 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001851 if err == nil {
1852 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1853 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 "device-id": dh.DeviceID, "error": err})
1855 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001856 }
1857 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001858 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001859 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001860 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001861 } //else
1862 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001863 "device-id": dh.DeviceID, "error": err})
1864 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001865}
1866
mpagenkoaa3afe92021-05-21 16:20:58 +00001867func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001868 aVersion string) *voltha.ImageState {
1869 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001870 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001871 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001872 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001873 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1874 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1875 if aVersion == dh.pLastUpgradeImageState.Version {
1876 pImageState = dh.pLastUpgradeImageState
1877 } else { //state request for an image version different from last processed image version
1878 pImageState = &voltha.ImageState{
1879 Version: aVersion,
1880 //we cannot state something concerning this version
1881 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1882 Reason: voltha.ImageState_NO_ERROR,
1883 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1884 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001885 }
1886 }
mpagenko38662d02021-08-11 09:45:19 +00001887 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001888}
1889
1890func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1891 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001892 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001893 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001894 dh.lockUpgradeFsm.RLock()
1895 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001896 dh.lockUpgradeFsm.RUnlock()
1897 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001898 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001899 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1900 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1901 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1902 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1903 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1904 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001905 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1906 dh.upgradeCanceled = true
1907 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1908 }
mpagenko45586762021-10-01 08:30:22 +00001909 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001910 } else {
mpagenko45586762021-10-01 08:30:22 +00001911 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001912 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1913 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1914 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1915 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1916 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1917 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001918 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1919 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001920 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1921 //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 +00001922 }
1923}
1924
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001925func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1926
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001928
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001929 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001930 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001931 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1932 pDevEntry.MutexOnuImageStatus.Lock()
1933 pDevEntry.POnuImageStatus = onuImageStatus
1934 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001935
1936 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001938 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1939 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001940 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1941 pDevEntry.MutexOnuImageStatus.Lock()
1942 pDevEntry.POnuImageStatus = nil
1943 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001944 return images, err
1945}
1946
Himani Chawla6d2ae152020-09-02 13:11:20 +05301947// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001948// #####################################################################################
1949
1950// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301951// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001952
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001954 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1955 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001956}
1957
1958// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001960
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001961 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001962 var err error
1963
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001964 // populate what we know. rest comes later after mib sync
1965 dh.device.Root = false
1966 dh.device.Vendor = "OpenONU"
1967 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001969 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001972
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 if !dh.IsReconciling() {
1974 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301975 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04001976 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1977 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301978 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001979 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301980 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001981 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001982 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001983
Himani Chawla4d908332020-08-31 12:30:20 +05301984 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001985 dh.ponPortNumber = dh.device.ParentPortNo
1986
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001987 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1988 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1989 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001990 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001991 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301992 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001993
1994 /*
1995 self._pon = PonPort.create(self, self._pon_port_number)
1996 self._pon.add_peer(self.parent_id, self._pon_port_number)
1997 self.logger.debug('adding-pon-port-to-agent',
1998 type=self._pon.get_port().type,
1999 admin_state=self._pon.get_port().admin_state,
2000 oper_status=self._pon.get_port().oper_status,
2001 )
2002 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002003 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302004 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002005 var ponPortNo uint32 = 1
2006 if dh.ponPortNumber != 0 {
2007 ponPortNo = dh.ponPortNumber
2008 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002009
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002010 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002011 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002012 PortNo: ponPortNo,
2013 Label: fmt.Sprintf("pon-%d", ponPortNo),
2014 Type: voltha.Port_PON_ONU,
2015 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302016 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002017 PortNo: ponPortNo}}, // Peer port is parent's port number
2018 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002019 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002020 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002021 e.Cancel(err)
2022 return
2023 }
2024 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302025 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002026 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002027 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002028}
2029
2030// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002032
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002033 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002034 var err error
2035 /*
2036 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2037 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2038 return nil
2039 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002041 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002042 e.Cancel(err)
2043 return
2044 }
2045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002046 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002048 // reconcilement will be continued after mib download is done
2049 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002050
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002051 /*
2052 ############################################################################
2053 # Setup Alarm handler
2054 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2055 device.serial_number)
2056 ############################################################################
2057 # Setup PM configuration for this device
2058 # Pass in ONU specific options
2059 kwargs = {
2060 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2061 'heartbeat': self.heartbeat,
2062 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2063 }
2064 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2065 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2066 self.logical_device_id, device.serial_number,
2067 grouped=True, freq_override=False, **kwargs)
2068 pm_config = self._pm_metrics.make_proto()
2069 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2070 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2071 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2072
2073 # Note, ONU ID and UNI intf set in add_uni_port method
2074 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2075 ani_ports=[self._pon])
2076
2077 # Code to Run OMCI Test Action
2078 kwargs_omci_test_action = {
2079 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2080 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2081 }
2082 serial_number = device.serial_number
2083 self._test_request = OmciTestRequest(self.core_proxy,
2084 self.omci_agent, self.device_id,
2085 AniG, serial_number,
2086 self.logical_device_id,
2087 exclusive=False,
2088 **kwargs_omci_test_action)
2089
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002090 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002091 else:
2092 self.logger.info('onu-already-activated')
2093 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002094
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002095 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002096}
2097
2098// doStateConnected get the device info and update to voltha core
2099// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302100//
2101// voltha-openolt-adapter/adaptercore/device_handler.go
2102// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002104
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002105 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302106 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002107 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002108 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002109}
2110
2111// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002113
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002114 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302115 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002116 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002117 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002118
2119 /*
2120 // Synchronous call to update device state - this method is run in its own go routine
2121 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2122 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002123 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 +00002124 return err
2125 }
2126 return nil
2127 */
2128}
2129
2130// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002131func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002132
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002133 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002134 var err error
2135
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002136 device := dh.device
2137 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002138 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002139 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140 e.Cancel(err)
2141 return
2142 }
2143
2144 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002146 /*
2147 // Update the all ports state on that device to disable
2148 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002149 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002150 return er
2151 }
2152
2153 //Update the device oper state and connection status
2154 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2155 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2156 dh.device = cloned
2157
2158 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002159 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002160 return er
2161 }
2162
2163 //get the child device for the parent device
2164 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2165 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002166 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002167 return err
2168 }
2169 for _, onuDevice := range onuDevices.Items {
2170
2171 // Update onu state as down in onu adapter
2172 onuInd := oop.OnuIndication{}
2173 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002174 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002175 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2176 if er != nil {
2177 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002178 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002179 //Do not return here and continue to process other ONUs
2180 }
2181 }
2182 // * Discovered ONUs entries need to be cleared , since after OLT
2183 // is up, it starts sending discovery indications again* /
2184 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002185 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002186 return nil
2187 */
Himani Chawla4d908332020-08-31 12:30:20 +05302188 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002189 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002190 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002191}
2192
Himani Chawla6d2ae152020-09-02 13:11:20 +05302193// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002194// #################################################################################
2195
2196// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302197// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002198
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302199// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002200func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002201 dh.lockDevice.RLock()
2202 pOnuDeviceEntry := dh.pOnuOmciDevice
2203 if aWait && pOnuDeviceEntry == nil {
2204 //keep the read sema short to allow for subsequent write
2205 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002207 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2208 // so it might be needed to wait here for that event with some timeout
2209 select {
2210 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002212 return nil
2213 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002214 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002215 // if written now, we can return the written value without sema
2216 return dh.pOnuOmciDevice
2217 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002218 }
mpagenko3af1f032020-06-10 08:53:41 +00002219 dh.lockDevice.RUnlock()
2220 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002221}
2222
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302223// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2225 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002226 dh.lockDevice.Lock()
2227 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002228 dh.pOnuOmciDevice = apDeviceEntry
2229 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002230 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302231 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002232 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002233}
2234
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302235// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302236//
2237//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302238func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002239 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002241 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002242 if deviceEntry == nil {
2243 /* costum_me_map in python code seems always to be None,
2244 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2245 /* also no 'clock' argument - usage open ...*/
2246 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002247 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2248 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2249 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2250 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2251 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002252 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002254 // fire deviceEntry ready event to spread to possibly waiting processing
2255 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002256 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002257 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002259 }
2260 // might be updated with some error handling !!!
2261 return nil
2262}
2263
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002265 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002266 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2267
2268 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002269
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002271 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002272 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2273 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002274 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302275
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002276 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002277 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002279
khenaidoo42dcdfd2021-10-19 17:34:12 -04002280 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002282 OperStatus: voltha.OperStatus_ACTIVATING,
2283 ConnStatus: voltha.ConnectStatus_REACHABLE,
2284 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002285 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302287 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2288 }
2289 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2290 if dh.GetDeviceTechProfOnReboot() {
2291 pDevEntry.MutexPersOnuConfig.Lock()
2292 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2293 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
2294 pDevEntry.MutexPersOnuConfig.Unlock()
2295 }
2296 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2297 if err := dh.StorePersistentData(ctx); err != nil {
2298 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2299 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002300 }
2301 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302302 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002303 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002304
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 pDevEntry.MutexPersOnuConfig.RLock()
2306 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2307 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 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 +00002309 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002310 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302311
2312 //VOL-4965: Recover previously Activating ONU during reconciliation.
2313 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2314 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2315 log.Fields{"device-id": dh.DeviceID})
2316 pDevEntry.MutexPersOnuConfig.Lock()
2317 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2318 pDevEntry.MutexPersOnuConfig.Unlock()
2319 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002320 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002322 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002323 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002324 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2325 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2326 // 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 +00002327 // 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 +00002328 // so let's just try to keep it simple ...
2329 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002331 if err != nil || device == nil {
2332 //TODO: needs to handle error scenarios
2333 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2334 return errors.New("Voltha Device not found")
2335 }
2336 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002337
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002339 return err
mpagenko3af1f032020-06-10 08:53:41 +00002340 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002341 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302342 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2343 /* this might be a good time for Omci Verify message? */
2344 verifyExec := make(chan bool)
2345 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2346 dh.device.Id, pDevEntry.PDevOmciCC, false,
2347 true, true) //exclusive and allowFailure (anyway not yet checked)
2348 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002349
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302350 /* give the handler some time here to wait for the OMCi verification result
2351 after Timeout start and try MibUpload FSM anyway
2352 (to prevent stopping on just not supported OMCI verification from ONU) */
2353 select {
2354 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2355 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2356 case testresult := <-verifyExec:
2357 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2358 case <-dh.deviceDeleteCommChan:
2359 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2360 return nil
2361 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002362 }
2363
2364 /* In py code it looks earlier (on activate ..)
2365 # Code to Run OMCI Test Action
2366 kwargs_omci_test_action = {
2367 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2368 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2369 }
2370 serial_number = device.serial_number
2371 self._test_request = OmciTestRequest(self.core_proxy,
2372 self.omci_agent, self.device_id,
2373 AniG, serial_number,
2374 self.logical_device_id,
2375 exclusive=False,
2376 **kwargs_omci_test_action)
2377 ...
2378 # Start test requests after a brief pause
2379 if not self._test_request_started:
2380 self._test_request_started = True
2381 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2382 reactor.callLater(tststart, self._test_request.start_collector)
2383
2384 */
2385 /* which is then: in omci_test_request.py : */
2386 /*
2387 def start_collector(self, callback=None):
2388 """
2389 Start the collection loop for an adapter if the frequency > 0
2390
2391 :param callback: (callable) Function to call to collect PM data
2392 """
2393 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2394 if callback is None:
2395 callback = self.perform_test_omci
2396
2397 if self.lc is None:
2398 self.lc = LoopingCall(callback)
2399
2400 if self.default_freq > 0:
2401 self.lc.start(interval=self.default_freq / 10)
2402
2403 def perform_test_omci(self):
2404 """
2405 Perform the initial test request
2406 """
2407 ani_g_entities = self._device.configuration.ani_g_entities
2408 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2409 is not None else None
2410 self._entity_id = ani_g_entities_ids[0]
2411 self.logger.info('perform-test', entity_class=self._entity_class,
2412 entity_id=self._entity_id)
2413 try:
2414 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2415 result = yield self._device.omci_cc.send(frame)
2416 if not result.fields['omci_message'].fields['success_code']:
2417 self.logger.info('Self-Test Submitted Successfully',
2418 code=result.fields[
2419 'omci_message'].fields['success_code'])
2420 else:
2421 raise TestFailure('Test Failure: {}'.format(
2422 result.fields['omci_message'].fields['success_code']))
2423 except TimeoutError as e:
2424 self.deferred.errback(failure.Failure(e))
2425
2426 except Exception as e:
2427 self.logger.exception('perform-test-Error', e=e,
2428 class_id=self._entity_class,
2429 entity_id=self._entity_id)
2430 self.deferred.errback(failure.Failure(e))
2431
2432 */
2433
2434 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002435 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002436
mpagenko1cc3cb42020-07-27 15:24:38 +00002437 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2438 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2439 * 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 +05302440 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002441 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302444 // Breaking this part of code due to sca complexity
2445 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2446 return err
2447}
2448
2449func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002451 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452 if pMibUlFsm.Is(mib.UlStDisabled) {
2453 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2454 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2455 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302456 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002457 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302458 //Determine ONU status and start/re-start MIB Synchronization tasks
2459 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 if pDevEntry.IsNewOnu() {
2461 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2462 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2463 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002464 }
Himani Chawla4d908332020-08-31 12:30:20 +05302465 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002466 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2467 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2468 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302469 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002470 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002471 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002472 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002474 "device-id": dh.DeviceID})
2475 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002476 }
2477 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2479 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002480 }
2481 return nil
2482}
2483
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002484func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002485 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002486 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302488 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002489
mpagenko900ee4b2020-10-12 11:56:34 +00002490 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2491 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2492 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002493 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002496 // abort: system behavior is just unstable ...
2497 return err
2498 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002499 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302500 if !dh.GetDeviceTechProfOnReboot() {
2501 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2502 }
mpagenko900ee4b2020-10-12 11:56:34 +00002503
2504 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002505 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002507 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2509 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002510 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002511 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002512
2513 //TODO!!! remove existing traffic profiles
2514 /* from py code, if TP's exist, remove them - not yet implemented
2515 self._tp = dict()
2516 # Let TP download happen again
2517 for uni_id in self._tp_service_specific_task:
2518 self._tp_service_specific_task[uni_id].clear()
2519 for uni_id in self._tech_profile_download_done:
2520 self._tech_profile_download_done[uni_id].clear()
2521 */
2522
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002524
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002526
mpagenkoe4782082021-11-25 12:04:26 +00002527 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002528 // abort: system behavior is just unstable ...
2529 return err
2530 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002531 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002533 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002535 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2536 OperStatus: voltha.OperStatus_DISCOVERED,
2537 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002538 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002540 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002541 // abort: system behavior is just unstable ...
2542 return err
2543 }
2544 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002546 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002547 return nil
2548}
2549
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002550func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002551 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2552 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2553 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2554 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002555 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302558 //VOL-5260: During race conditions when adoptDevice has not yet completed
2559 // and deleteDevice is issued , returning error will further prevent clean up
2560 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002561 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302562 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2563 logger.Error(ctx, errMsg)
2564 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002565 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002566 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002567 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002568 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 pDevEntry.MutexOnuImageStatus.RLock()
2570 if pDevEntry.POnuImageStatus != nil {
2571 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002572 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002573 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002574
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002575 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002576 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002577 }
2578 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002580 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002582 }
mpagenko101ac942021-11-16 15:01:29 +00002583 //stop any deviceHandler reconcile processing (if running)
2584 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002585 //port lock/unlock FSM's may be active
2586 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002588 }
2589 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002591 }
2592 //techProfile related PonAniConfigFsm FSM may be active
2593 if dh.pOnuTP != nil {
2594 // should always be the case here
2595 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 if dh.pOnuTP.PAniConfigFsm != nil {
2597 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2598 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002599 }
mpagenko900ee4b2020-10-12 11:56:34 +00002600 }
2601 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002602 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002603 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002605 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002606 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002607 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002608 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002609 } else {
2610 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002611 }
2612 }
2613 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302614
2615 dh.mutexCollectorFlag.Lock()
2616 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2617 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002618 // Stop collector routine
2619 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302620 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002621 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302622 dh.mutexCollectorFlag.Unlock()
2623
2624 dh.mutextAlarmManagerFlag.Lock()
2625 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2626 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302627 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302628 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302629 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302630 dh.mutextAlarmManagerFlag.Unlock()
2631
2632 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2633 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2634 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002635 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302636 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002637 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302638 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302639
Girish Gowdrae95687a2021-09-08 16:30:58 -07002640 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2641
mpagenko80622a52021-02-09 16:53:23 +00002642 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002644 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002645 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002647 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002648 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002649 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2650 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2651 // (even though it may also run into direct cancellation, a bit hard to verify here)
2652 // so don't set 'dh.upgradeCanceled = true' here!
2653 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2654 }
mpagenko38662d02021-08-11 09:45:19 +00002655 }
mpagenko80622a52021-02-09 16:53:23 +00002656
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002658 return nil
2659}
2660
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302661//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2663 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 +05302664
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002665 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002667 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002669 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002670 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002671 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002672
mpagenkoa40e99a2020-11-17 13:50:39 +00002673 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2674 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2675 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2676 * disable/enable toggling here to allow traffic
2677 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2678 * like the py comment says:
2679 * # start by locking all the unis till mib sync and initial mib is downloaded
2680 * # this way we can capture the port down/up events when we are ready
2681 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302682
mpagenkoa40e99a2020-11-17 13:50:39 +00002683 // Init Uni Ports to Admin locked state
2684 // *** should generate UniLockStateDone event *****
2685 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002687 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002689 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002690 }
2691}
2692
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302693//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2695 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302696 /* Mib download procedure -
2697 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2698 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002699 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002700 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002702 return
2703 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302705 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002706 if pMibDlFsm.Is(mib.DlStDisabled) {
2707 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2708 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 +05302709 // maybe try a FSM reset and then again ... - TODO!!!
2710 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002711 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302712 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2714 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302715 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002716 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302717 //Begin MIB data download (running autonomously)
2718 }
2719 }
2720 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302723 // maybe try a FSM reset and then again ... - TODO!!!
2724 }
2725 /***** Mib download started */
2726 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302728 }
2729}
2730
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302731//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302733 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002734 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2735 if pDevEntry == nil {
2736 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2737 return
2738 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002739 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002740 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002742 // update device info in core
2743 pDevEntry.MutexPersOnuConfig.RLock()
2744 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2745 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2746 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2747 pDevEntry.MutexPersOnuConfig.RUnlock()
2748 dh.logicalDeviceID = dh.DeviceID
2749 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2750 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2751 }
2752 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002753 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2754 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2755 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2756 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002757 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002759 ConnStatus: voltha.ConnectStatus_REACHABLE,
2760 OperStatus: voltha.OperStatus_ACTIVE,
2761 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302762 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302764 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302766 }
2767 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302768 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302770 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002771 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002772
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002774 var waitForOmciProcessor sync.WaitGroup
2775 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002776 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002777 go dh.StartCollector(ctx, &waitForOmciProcessor)
2778 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002779 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 if !dh.GetAlarmManagerIsRunning(ctx) {
2781 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002782 }
2783
Girish Gowdrae95687a2021-09-08 16:30:58 -07002784 // Start flow handler routines per UNI
2785 for _, uniPort := range dh.uniEntityMap {
2786 // only if this port was enabled for use by the operator at startup
2787 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2788 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2789 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2790 }
2791 }
2792 }
2793
Girish Gowdrae0140f02021-02-02 16:55:09 -08002794 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002796 // There is no way we should be landing here, but if we do then
2797 // there is nothing much we can do about this other than log error
2798 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2799 }
2800
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002802
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 pDevEntry.MutexPersOnuConfig.RLock()
2804 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2805 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302806 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002807 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002808 dh.mutexForDisableDeviceRequested.Lock()
2809 dh.disableDeviceRequested = true
2810 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002811 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002812 // reconcilement will be continued after ani config is done
2813 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002814 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002815 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002816 dh.mutexForDisableDeviceRequested.RLock()
2817 if !dh.disableDeviceRequested {
2818 if dh.pUnlockStateFsm == nil {
2819 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2820 } else { //UnlockStateFSM already init
2821 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2822 dh.runUniLockFsm(ctx, false)
2823 }
2824 dh.mutexForDisableDeviceRequested.RUnlock()
2825 } else {
2826 dh.mutexForDisableDeviceRequested.RUnlock()
2827 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002828 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302829 }
2830}
2831
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302832//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2834 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302835
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002836 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302837 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2838 if dh.GetDeviceTechProfOnReboot() {
2839 if dh.CheckForDeviceTechProf(ctx) {
2840 go dh.DeviceFlowConfigOnReboot(ctx)
2841 }
2842 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002843 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002844 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002845 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2846 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002847 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002849 return
2850 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 pDevEntry.MutexPersOnuConfig.Lock()
2852 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2853 pDevEntry.MutexPersOnuConfig.Unlock()
2854 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002855 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002857 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302858 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302859 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 +00002860 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002861 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302862
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002863 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302864
Himani Chawla26e555c2020-08-31 12:30:20 +05302865 }
2866}
2867
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302868//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002870 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002872
mpagenko44bd8362021-11-15 11:40:05 +00002873 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002874 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002875 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002876 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002877 OperStatus: voltha.OperStatus_UNKNOWN,
2878 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002879 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002880 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002881 }
2882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002884 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002885 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002886
2887 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002888 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002890 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002891 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002893 return
2894 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 pDevEntry.MutexPersOnuConfig.Lock()
2896 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2897 pDevEntry.MutexPersOnuConfig.Unlock()
2898 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002900 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002901 }
mpagenko900ee4b2020-10-12 11:56:34 +00002902}
2903
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302904//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002907 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002908 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002910 ConnStatus: voltha.ConnectStatus_REACHABLE,
2911 OperStatus: voltha.OperStatus_ACTIVE,
2912 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002913 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002915 }
2916
dbainbri4d3a0dc2020-12-02 00:33:42 +00002917 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002919 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002920 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002921
2922 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002923 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002926 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002928 return
2929 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002930 pDevEntry.MutexPersOnuConfig.Lock()
2931 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2932 pDevEntry.MutexPersOnuConfig.Unlock()
2933 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002936 }
mpagenko900ee4b2020-10-12 11:56:34 +00002937}
2938
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302939//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002940func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2941 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2942 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002943 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002944 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002945 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002946 OperStatus: voltha.OperStatus_FAILED,
2947 }); err != nil {
2948 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2949 }
2950}
2951
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2953 if devEvent == cmn.OmciAniConfigDone {
2954 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002955 // attention: the device reason update is done based on ONU-UNI-Port related activity
2956 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002958 // 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 +00002959 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302960 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002962 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2963 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2964 dh.mutexReconcilingFirstPassFlag.Lock()
2965 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302966 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002967 dh.reconcilingFirstPass = false
2968 go dh.ReconcileDeviceFlowConfig(ctx)
2969 }
2970 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002971 }
2972 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002974 // attention: the device reason update is done based on ONU-UNI-Port related activity
2975 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002977 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2978 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002979 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002980 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302981}
2982
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002984 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302986 // attention: the device reason update is done based on ONU-UNI-Port related activity
2987 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302988
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2990 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002991 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002992 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002993 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002994 }
2995 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002997 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002998 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002999 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303000 }
mpagenkof1fc3862021-02-16 10:09:52 +00003001
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003002 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003003 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003005 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003006 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003007 }
3008 } else {
3009 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003010 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003011 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303012}
3013
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303014// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303016 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003018 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003019 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003020 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003022 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003023 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003024 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003026 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003027 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003028 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003029 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003030 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003031 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003032 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003033 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003034 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003035 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003036 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003037 case cmn.UniEnableStateFailed:
3038 {
3039 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3040 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003042 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003043 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003044 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003045 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003046 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003047 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003049 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003050 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003051 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003052 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003053 default:
3054 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003055 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003056 }
3057 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003058}
3059
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003061 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003062 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303063 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003064 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003065 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003066 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303067 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003069 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003070 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 +00003071 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003072 //store UniPort with the System-PortNumber key
3073 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003074 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003075 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003076 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003077 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003078 } //error logging already within UniPort method
3079 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303080 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003081 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003082 }
3083 }
3084}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003085
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3087 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003088 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003089 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003090 return
3091 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003092 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003094 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3095 for _, mgmtEntityID := range pptpInstKeys {
3096 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003098 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3099 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003100 }
3101 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003102 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003103 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003105 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3106 for _, mgmtEntityID := range veipInstKeys {
3107 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003108 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003109 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3110 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003111 }
3112 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003113 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003114 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003115 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003116 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3117 for _, mgmtEntityID := range potsInstKeys {
3118 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003119 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003120 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3121 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003122 }
3123 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003124 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003125 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003126 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003127 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003128 return
3129 }
3130
mpagenko2c3f6c52021-11-23 11:22:10 +00003131 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3132 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3133 // 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 -07003134 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3135 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3136 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003137 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3138 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303139 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003140 for i := 0; i < int(uniCnt); i++ {
3141 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003142 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003143 }
3144}
3145
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003146// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3147func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003148 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303149 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003150 // with following remark:
3151 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3152 // # load on the core
3153
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003154 // 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 +00003155
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003156 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003157 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3159 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
3160 uniPort.SetOperState(vc.OperStatus_ACTIVE)
3161 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003162 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003163 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003164 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003166 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 PortNo: port.PortNo,
3168 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003169 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003170 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 -04003171 }
3172 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003173 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303174 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003175 }
mpagenko3af1f032020-06-10 08:53:41 +00003176 }
3177 }
3178}
3179
3180// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003181func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3182 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003183 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3184 for uniNo, uniPort := range dh.uniEntityMap {
3185 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003186
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003187 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3188 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
3189 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
3190 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003191 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003193 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003194 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003195 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196 PortNo: port.PortNo,
3197 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003198 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003199 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 -04003200 }
3201 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003202 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303203 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003204 }
3205
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003206 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003207 }
3208}
3209
3210// ONU_Active/Inactive announcement on system KAFKA bus
3211// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00003212func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003213 var de voltha.DeviceEvent
3214 eventContext := make(map[string]string)
3215 //Populating event context
3216 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003217 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003218 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003219 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003220 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003221 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 +00003222 }
3223 oltSerialNumber := parentDevice.SerialNumber
3224
3225 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3226 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3227 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303228 eventContext["olt-serial-number"] = oltSerialNumber
3229 eventContext["device-id"] = aDeviceID
3230 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003231 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3233 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003234 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3235 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003236 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3237 deviceEntry.MutexPersOnuConfig.RUnlock()
3238 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003239 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003240 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3241 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3242 } else {
3243 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3244 log.Fields{"device-id": aDeviceID})
3245 return
3246 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003247
3248 /* Populating device event body */
3249 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303250 de.ResourceId = aDeviceID
3251 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003252 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3253 de.Description = fmt.Sprintf("%s Event - %s - %s",
3254 cEventObjectType, cOnuActivatedEvent, "Raised")
3255 } else {
3256 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3257 de.Description = fmt.Sprintf("%s Event - %s - %s",
3258 cEventObjectType, cOnuActivatedEvent, "Cleared")
3259 }
3260 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303261 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003262 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303263 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003264 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303265 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303266 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003267}
3268
Himani Chawla4d908332020-08-31 12:30:20 +05303269// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003270func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303271 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003272 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303273 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003274 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003275 sFsmName = "LockStateFSM"
3276 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003277 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003278 sFsmName = "UnLockStateFSM"
3279 }
mpagenko3af1f032020-06-10 08:53:41 +00003280
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003281 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00003282 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003283 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003284 return
3285 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003287 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303288 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003289 dh.pLockStateFsm = pLSFsm
3290 } else {
3291 dh.pUnlockStateFsm = pLSFsm
3292 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003293 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003294 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003295 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003296 }
3297}
3298
3299// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003300func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003301 /* Uni Port lock/unlock procedure -
3302 ***** should run via 'adminDone' state and generate the argument requested event *****
3303 */
3304 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303305 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003306 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003307 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3308 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3310 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003311 }
3312 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003313 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003314 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3315 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003316 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3317 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003318 }
3319 }
3320 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003321 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3322 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003323 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003324 // maybe try a FSM reset and then again ... - TODO!!!
3325 } else {
3326 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003327 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003329 }
3330 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003331 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003332 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003333 // maybe try a FSM reset and then again ... - TODO!!!
3334 }
3335 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003336 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003337 // maybe try a FSM reset and then again ... - TODO!!!
3338 }
3339}
3340
mpagenko80622a52021-02-09 16:53:23 +00003341// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003342// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303343//
3344//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003345func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303346 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003347 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003348 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003349 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003350 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303351 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003352 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003353 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003354 sFsmName, chUpgradeFsm)
3355 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003356 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003357 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3359 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003360 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003361 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303362 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003363 }
mpagenko59862f02021-10-11 08:53:18 +00003364 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003365 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3366 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003367 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3368 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003369 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003371 } else {
3372 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003373 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003374 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303375 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003376 }
3377 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003378 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003379 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303380 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003381 }
3382 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003383 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303384 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003385 }
3386 return nil
3387}
3388
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003389// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3390func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003391 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003393 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003394 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3395 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003396 dh.pLastUpgradeImageState = apImageState
3397 dh.lockUpgradeFsm.Unlock()
3398 //signal upgradeFsm removed using non-blocking channel send
3399 select {
3400 case dh.upgradeFsmChan <- struct{}{}:
3401 default:
3402 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003403 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003404 }
mpagenko80622a52021-02-09 16:53:23 +00003405}
3406
mpagenko15ff4a52021-03-02 10:09:20 +00003407// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3408func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003409 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003410 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003411 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003412 return
3413 }
3414
3415 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003416 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003417 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003418 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3419 dh.lockUpgradeFsm.RUnlock()
3420 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3421 return
3422 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003423 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003424 if pUpgradeStatemachine != nil {
3425 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3426 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427 UpgradeState := pUpgradeStatemachine.Current()
3428 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3429 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3430 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003431 // 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 +00003432 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003433 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3434 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003435 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003436 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003437 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003438 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3439 dh.upgradeCanceled = true
3440 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3441 }
mpagenko15ff4a52021-03-02 10:09:20 +00003442 return
3443 }
mpagenko59862f02021-10-11 08:53:18 +00003444 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3446 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003447 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003449 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3450 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003451 return
3452 }
3453 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003454 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003455 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3457 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003458 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3459 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003460 return
3461 }
3462 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003464 }
3465 } else {
3466 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 +00003467 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003468 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3469 dh.upgradeCanceled = true
3470 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3471 }
mpagenko1f8e8822021-06-25 14:10:21 +00003472 }
mpagenko15ff4a52021-03-02 10:09:20 +00003473 return
3474 }
mpagenko59862f02021-10-11 08:53:18 +00003475 dh.lockUpgradeFsm.RUnlock()
3476 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3477 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003478 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3479 dh.upgradeCanceled = true
3480 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3481 }
mpagenko59862f02021-10-11 08:53:18 +00003482 return
3483 }
3484 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3485 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3486 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3487 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3488 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3489 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3490 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003491 }
mpagenko15ff4a52021-03-02 10:09:20 +00003492 }
3493 }
3494 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003495 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003496 }
mpagenko59862f02021-10-11 08:53:18 +00003497 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003498}
3499
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303500// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003502
3503 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003505 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003506 kvbackend := &db.Backend{
3507 Client: dh.pOpenOnuAc.kvClient,
3508 StoreType: dh.pOpenOnuAc.KVStoreType,
3509 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003510 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003511 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3512 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003513
mpagenkoaf801632020-07-03 10:00:42 +00003514 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003515}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303516
3517//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003518func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303519 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003520
mpagenkodff5dda2020-08-28 11:52:01 +00003521 for _, field := range flow.GetOfbFields(apFlowItem) {
3522 switch field.Type {
3523 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3524 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003525 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003526 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3527 }
mpagenko01e726e2020-10-23 09:45:29 +00003528 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003529 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3530 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303531 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003532 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303533 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3534 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003535 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3536 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003537 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303539 return
mpagenkodff5dda2020-08-28 11:52:01 +00003540 }
3541 }
mpagenko01e726e2020-10-23 09:45:29 +00003542 */
mpagenkodff5dda2020-08-28 11:52:01 +00003543 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3544 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303545 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003546 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303547 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003548 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303549 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003550 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303552 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003553 }
3554 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3555 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303556 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003557 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303558 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003559 }
3560 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3561 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003562 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003563 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3564 }
3565 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3566 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003567 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003568 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3569 }
3570 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3571 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003572 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003573 "IPv4-DST": field.GetIpv4Dst()})
3574 }
3575 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3576 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003578 "IPv4-SRC": field.GetIpv4Src()})
3579 }
3580 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3581 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003582 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003583 "Metadata": field.GetTableMetadata()})
3584 }
3585 /*
3586 default:
3587 {
3588 //all other entires ignored
3589 }
3590 */
3591 }
3592 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303593}
mpagenkodff5dda2020-08-28 11:52:01 +00003594
khenaidoo7d3c5582021-08-11 18:09:44 -04003595func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003596 for _, action := range flow.GetActions(apFlowItem) {
3597 switch action.Type {
3598 /* not used:
3599 case of.OfpActionType_OFPAT_OUTPUT:
3600 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003601 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003602 "Output": action.GetOutput()})
3603 }
3604 */
3605 case of.OfpActionType_OFPAT_PUSH_VLAN:
3606 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003608 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3609 }
3610 case of.OfpActionType_OFPAT_SET_FIELD:
3611 {
3612 pActionSetField := action.GetSetField()
3613 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003615 "OxcmClass": pActionSetField.Field.OxmClass})
3616 }
3617 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303618 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003619 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303620 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003621 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303622 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003623 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303624 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003625 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003627 "Type": pActionSetField.Field.GetOfbField().Type})
3628 }
3629 }
3630 /*
3631 default:
3632 {
3633 //all other entires ignored
3634 }
3635 */
3636 }
3637 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303638}
3639
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303640// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003642 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303643 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3644 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303645 var loSetPcp uint8
3646 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303647 var loIPProto uint32
3648 /* the TechProfileId is part of the flow Metadata - compare also comment within
3649 * OLT-Adapter:openolt_flowmgr.go
3650 * Metadata 8 bytes:
3651 * Most Significant 2 Bytes = Inner VLAN
3652 * Next 2 Bytes = Tech Profile ID(TPID)
3653 * Least Significant 4 Bytes = Port ID
3654 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3655 * subscriber related flows.
3656 */
3657
dbainbri4d3a0dc2020-12-02 00:33:42 +00003658 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303659 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003660 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003661 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003662 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303663 }
mpagenko551a4d42020-12-08 18:09:20 +00003664 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003665 loCookie := apFlowItem.GetCookie()
3666 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303667 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003668 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303669 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303670
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303671 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003672 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303673 if loIPProto == 2 {
3674 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3675 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003676 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003677 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303678 return nil
3679 }
mpagenko01e726e2020-10-23 09:45:29 +00003680 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003681 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003682
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303683 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3684 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003685 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003687 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3688 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3689 //TODO!!: Use DeviceId within the error response to rwCore
3690 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003691 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003692 }
3693 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003695 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303696 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3697 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3698 loSetVlan = loMatchVlan
3699 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 +00003700 } else {
3701 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3702 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3703 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303704 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003705 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003706 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003707 }
mpagenko9a304ea2020-12-16 15:54:01 +00003708
khenaidoo42dcdfd2021-10-19 17:34:12 -04003709 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003710 if apFlowMetaData != nil {
3711 meter = apFlowMetaData.Meters[0]
3712 }
mpagenkobc4170a2021-08-17 16:42:10 +00003713 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3714 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3715 // when different rules are requested concurrently for the same uni
3716 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3717 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3718 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3720 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003721 //SetUniFlowParams() may block on some rule that is suspended-to-add
3722 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003723 // Also the error is returned to caller via response channel
3724 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303725 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003726 dh.lockVlanConfig.RUnlock()
3727 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003728 return
mpagenkodff5dda2020-08-28 11:52:01 +00003729 }
mpagenkobc4170a2021-08-17 16:42:10 +00003730 dh.lockVlanConfig.RUnlock()
3731 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003732 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303733 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003734 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003735 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003736 if err != nil {
3737 *respChan <- err
3738 }
mpagenko01e726e2020-10-23 09:45:29 +00003739}
3740
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303741// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003742func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003743 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3744 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3745 //no extra check is done on the rule parameters
3746 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3747 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3748 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3749 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003750 // - 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 +00003751 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003752 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003753
3754 /* TT related temporary workaround - should not be needed anymore
3755 for _, field := range flow.GetOfbFields(apFlowItem) {
3756 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3757 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003759 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3760 if loIPProto == 2 {
3761 // 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 +00003762 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003763 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003764 return nil
3765 }
3766 }
3767 } //for all OfbFields
3768 */
3769
mpagenko9a304ea2020-12-16 15:54:01 +00003770 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003771 dh.lockVlanConfig.RLock()
3772 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003773 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3774 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003775 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3776 return
mpagenko01e726e2020-10-23 09:45:29 +00003777 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003778 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003779 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003780 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003781 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003782 // Push response on the response channel
3783 if respChan != nil {
3784 // 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
3785 select {
3786 case *respChan <- nil:
3787 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3788 default:
3789 }
3790 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003792}
3793
Himani Chawla26e555c2020-08-31 12:30:20 +05303794// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003795// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003796// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003797func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303798 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 +05303799 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003800
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003801 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003802 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3804 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003805 }
3806
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303807 if dh.pDeviceStateFsm.Current() == devStDown {
3808 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3809 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3810 }
3811
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003812 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3813 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303814 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003815 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003816 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3817 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3819 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003820 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3822 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003823 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3824 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003825 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003826 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303827 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003828 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3830 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003831 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003832 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003833 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3834 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003835 }
3836 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003837 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003838 "device-id": dh.DeviceID})
3839 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003840 }
3841 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003842 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003843 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3844 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003845 }
3846 return nil
3847}
3848
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303849// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003850// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003851func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003852 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003854 for _, uniPort := range dh.uniEntityMap {
3855 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003856 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003857 pCurrentUniPort = uniPort
3858 break //found - end search loop
3859 }
3860 }
3861 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003862 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003864 return
3865 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003866 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003867}
3868
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303869// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003871 //TODO!! verify and start pending flow configuration
3872 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3873 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303874 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003875 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003876 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003877 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003878 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003879 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003880 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003881 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003882 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003883 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3884 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003885 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003886 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003887 } else {
3888 /***** UniVlanConfigFsm continued */
3889 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3891 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003892 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003893 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3894 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003895 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003896 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003897 } else {
3898 /***** UniVlanConfigFsm continued */
3899 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003900 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3901 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003902 }
mpagenkodff5dda2020-08-28 11:52:01 +00003903 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003904 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3906 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003907 }
3908 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003909 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 +00003910 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3911 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003912 }
3913 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003914 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003916 }
mpagenkof1fc3862021-02-16 10:09:52 +00003917 } else {
3918 dh.lockVlanConfig.RUnlock()
3919 }
mpagenkodff5dda2020-08-28 11:52:01 +00003920}
3921
Akash Soni3de0e062024-12-11 16:37:26 +05303922// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3923func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3924 dh.lockVlanConfig.Lock()
3925 defer dh.lockVlanConfig.Unlock()
3926
3927 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3928 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3929 if pVlanFilterStatemachine != nil {
3930 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3931 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3932 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3933 })
3934 } else {
3935 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3936 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3937 })
3938 }
3939 } else {
3940 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3941 "device-id": dh.DeviceID, "UniPort": uniID,
3942 })
3943 }
3944 } else {
3945 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3946 "device-id": dh.DeviceID, "UniPort": uniID,
3947 })
3948 }
3949}
3950
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303951// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003952// 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 +00003953func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003954 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003955 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003956 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003957 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003958 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003959 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003960}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003961
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303962// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003963func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003964 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3965 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3966 // obviously then parallel processing on the cancel must be avoided
3967 // deadline context to ensure completion of background routines waited for
3968 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3969 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3970 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303971 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003972
Akash Soni840f8d62024-12-11 19:37:06 +05303973 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3974 if err != nil {
3975 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3976 return err
3977 }
3978 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003979}
3980
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303981// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3982// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003983func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3984 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003985
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003986 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303987 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003988 return nil
3989 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003990 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003991
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003992 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003993 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003994 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3995 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003996 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003997 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003998
mpagenkof1fc3862021-02-16 10:09:52 +00003999 if aWriteToKvStore {
4000 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4001 }
4002 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004003}
4004
dbainbri4d3a0dc2020-12-02 00:33:42 +00004005func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004006 defer cancel() //ensure termination of context (may be pro forma)
4007 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004008 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004009 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004010}
4011
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304012// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4013//
4014// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004015func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4016 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4017 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4018 dh.mutexDeviceReason.Lock()
4019 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004020 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004021 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004022 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023 DeviceId: dh.DeviceID,
4024 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004025 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004026 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004027 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004028 return err
4029 }
mpagenkoe4782082021-11-25 12:04:26 +00004030 } else {
4031 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 +00004032 }
mpagenkoe4782082021-11-25 12:04:26 +00004033 dh.deviceReason = deviceReason
4034 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4035 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004036 return nil
4037}
4038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004039func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
4040 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004041 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004042 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4043 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004044 }
mpagenkof1fc3862021-02-16 10:09:52 +00004045 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004046}
4047
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304048func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4049 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4050 if pDevEntry != nil {
4051 pDevEntry.MutexPersOnuConfig.Lock()
4052 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4053 pDevEntry.MutexPersOnuConfig.Unlock()
4054 } else {
4055 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4056 }
4057}
4058
4059func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4060 rebootFlag := false
4061 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4062 if pDevEntry != nil {
4063 pDevEntry.MutexPersOnuConfig.RLock()
4064 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4065 pDevEntry.MutexPersOnuConfig.RUnlock()
4066 } else {
4067 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4068 }
4069 return rebootFlag
4070}
4071
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004072// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004073// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004074func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4075 dh.lockDevice.RLock()
4076 defer dh.lockDevice.RUnlock()
4077 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004078 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004079 }
4080 return 0, errors.New("error-fetching-uni-port")
4081}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004082
4083// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004084func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4085 var errorsList []error
4086 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 -08004087
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004088 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4089 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4090 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4091
4092 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4093 // successfully.
4094 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4095 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4096 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004097 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 -08004098 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004099 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004100 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004101 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004102}
4103
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004104func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4105 var err error
4106 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004107 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004108
4109 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004110 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004111 errorsList = append(errorsList, err)
4112 }
4113 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004114 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004115
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004116 return errorsList
4117}
4118
4119func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4120 var err error
4121 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004122 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004123 // Check if group metric related config is updated
4124 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004125 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4126 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4127 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004128
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004129 if ok && m.Frequency != v.GroupFreq {
4130 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004131 errorsList = append(errorsList, err)
4132 }
4133 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004134 if ok && m.Enabled != v.Enabled {
4135 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004136 errorsList = append(errorsList, err)
4137 }
4138 }
4139 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004140 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004141 return errorsList
4142}
4143
4144func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4145 var err error
4146 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004147 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004148 // Check if standalone metric related config is updated
4149 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004150 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4151 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4152 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004153
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004154 if ok && m.Frequency != v.SampleFreq {
4155 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004156 errorsList = append(errorsList, err)
4157 }
4158 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004159 if ok && m.Enabled != v.Enabled {
4160 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004161 errorsList = append(errorsList, err)
4162 }
4163 }
4164 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004165 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004166 return errorsList
4167}
4168
4169// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004170func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004171 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08004172
4173 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004174 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304175 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004176 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004177 // Initialize the next metric collection time.
4178 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4179 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004181 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304182 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4183 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004184 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304185
Girish Gowdrae09a6202021-01-12 18:10:59 -08004186 select {
4187 case <-dh.stopCollector:
4188 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004189 // Stop the L2 PM FSM
4190 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4192 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4193 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004194 }
4195 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004196 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004197 }
4198 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004199 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4200 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004201 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004202 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4203 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004204 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004205
Girish Gowdrae09a6202021-01-12 18:10:59 -08004206 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304207 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004208 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4209 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4210 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4211 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004212 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004213 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4214 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004215 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004216 } else {
4217 if dh.pmConfigs.Grouped { // metrics are managed as a group
4218 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004219 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004220
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004221 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4222 // 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 -08004223 // 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 +00004224 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4225 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004226 }
4227 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004228 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4229 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4230 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4231 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004232 }
4233 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004234 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004235
4236 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004237 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4238 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4239 // 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 -08004240 // 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 +00004241 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004242 prevInternal := g.NextCollectionInterval
4243 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004244 }
4245 }
4246 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004247 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4248 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4249 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004250 prevInternal := m.NextCollectionInterval
4251 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004252 }
4253 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004254 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004255 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004256 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004257 } */
4258 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004259 }
4260 }
4261}
kesavandfdf77632021-01-26 23:40:33 -05004262
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304263//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304264func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4265
4266 singleValResp := extension.SingleSetValueResponse{
4267 Response: &extension.SetValueResponse{
4268 Status: extension.SetValueResponse_OK,
4269 },
4270 }
4271
4272 return &singleValResp
4273}
4274
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004275func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004276
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004277 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4278 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004279}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004280
Himani Chawla43f95ff2021-06-03 00:24:12 +05304281func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4282 if dh.pOnuMetricsMgr == nil {
4283 return &extension.SingleGetValueResponse{
4284 Response: &extension.GetValueResponse{
4285 Status: extension.GetValueResponse_ERROR,
4286 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4287 },
4288 }
4289 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304290 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304291 return resp
4292}
4293
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004294func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4295
4296 var err error
4297 var pDevOmciCC *cmn.OmciCC
4298 if dh.pOnuOmciDevice == nil {
4299 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4300 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4301 } else {
4302 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4303 if pDevOmciCC == nil {
4304 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4305 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4306 }
4307 }
4308 if err != nil {
4309 return &extension.SingleGetValueResponse{
4310 Response: &extension.GetValueResponse{
4311 Status: extension.GetValueResponse_ERROR,
4312 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4313 },
4314 },
4315 err
4316 }
4317 return pDevOmciCC.GetOmciCounters(), nil
4318}
4319
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304320//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004321func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4322 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004323 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004324 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004325 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004326}
4327
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004328func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004329 var pAdapterFsm *cmn.AdapterFsm
4330 //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 +00004331 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004332 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004333 {
mpagenkofbf577d2021-10-12 11:44:33 +00004334 if dh.pOnuOmciDevice != nil {
4335 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4336 } else {
4337 return true //FSM not active - so there is no activity on omci
4338 }
mpagenkof1fc3862021-02-16 10:09:52 +00004339 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004340 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004341 {
mpagenkofbf577d2021-10-12 11:44:33 +00004342 if dh.pOnuOmciDevice != nil {
4343 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4344 } else {
4345 return true //FSM not active - so there is no activity on omci
4346 }
mpagenkof1fc3862021-02-16 10:09:52 +00004347 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004348 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004349 {
mpagenkofbf577d2021-10-12 11:44:33 +00004350 if dh.pLockStateFsm != nil {
4351 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4352 } else {
4353 return true //FSM not active - so there is no activity on omci
4354 }
mpagenkof1fc3862021-02-16 10:09:52 +00004355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004356 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004357 {
mpagenkofbf577d2021-10-12 11:44:33 +00004358 if dh.pUnlockStateFsm != nil {
4359 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4360 } else {
4361 return true //FSM not active - so there is no activity on omci
4362 }
mpagenkof1fc3862021-02-16 10:09:52 +00004363 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004364 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004365 {
mpagenkofbf577d2021-10-12 11:44:33 +00004366 if dh.pOnuMetricsMgr != nil {
4367 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004368 } else {
4369 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004370 }
4371 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004372 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004373 {
4374 dh.lockUpgradeFsm.RLock()
4375 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004376 if dh.pOnuUpradeFsm != nil {
4377 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4378 } else {
4379 return true //FSM not active - so there is no activity on omci
4380 }
mpagenko80622a52021-02-09 16:53:23 +00004381 }
mpagenkof1fc3862021-02-16 10:09:52 +00004382 default:
4383 {
4384 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004385 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004386 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004387 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004388 }
mpagenkofbf577d2021-10-12 11:44:33 +00004389 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4390 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4391 }
4392 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004393}
4394
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004395func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4396 for _, v := range dh.pOnuTP.PAniConfigFsm {
4397 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004398 return false
4399 }
4400 }
4401 return true
4402}
4403
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304404//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004405func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004406 dh.lockVlanConfig.RLock()
4407 defer dh.lockVlanConfig.RUnlock()
4408 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004409 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004410 return false
4411 }
4412 }
4413 return true //FSM not active - so there is no activity on omci
4414}
4415
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304416//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004417func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4418 dh.lockVlanConfig.RLock()
4419 defer dh.lockVlanConfig.RUnlock()
4420 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004421 if v.PAdaptFsm.PFsm != nil {
4422 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004423 return true //there is at least one VLAN FSM with some active configuration
4424 }
4425 }
4426 }
4427 return false //there is no VLAN FSM with some active configuration
4428}
4429
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004430func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004431 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4432 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4433 return false
4434 }
4435 }
4436 // a further check is done to identify, if at least some data traffic related configuration exists
4437 // 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])
4438 return dh.checkUserServiceExists(ctx)
4439}
4440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004441func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304442 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 +00004443 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004444 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004445 // TODO: fatal error reset ONU, delete deviceHandler!
4446 return
4447 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004448 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4449 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004450}
4451
4452func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4453 dh.mutexCollectorFlag.Lock()
4454 dh.collectorIsRunning = flagValue
4455 dh.mutexCollectorFlag.Unlock()
4456}
4457
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004458func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004459 dh.mutexCollectorFlag.RLock()
4460 flagValue := dh.collectorIsRunning
4461 dh.mutexCollectorFlag.RUnlock()
4462 return flagValue
4463}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304464
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304465func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4466 dh.mutextAlarmManagerFlag.Lock()
4467 dh.alarmManagerIsRunning = flagValue
4468 dh.mutextAlarmManagerFlag.Unlock()
4469}
4470
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004471func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304472 dh.mutextAlarmManagerFlag.RLock()
4473 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004474 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304475 dh.mutextAlarmManagerFlag.RUnlock()
4476 return flagValue
4477}
4478
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004479func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004480 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304481
4482 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004483 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304484 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304485 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304486 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304487 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004488 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4489 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304490 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304491 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004492 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4493 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304494 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304495 }
4496}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004497
Girish Gowdrae95687a2021-09-08 16:30:58 -07004498func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4499 dh.mutexFlowMonitoringRoutineFlag.Lock()
4500 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004501 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004502 dh.isFlowMonitoringRoutineActive[uniID] = flag
4503}
4504
4505func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4506 dh.mutexFlowMonitoringRoutineFlag.RLock()
4507 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4508 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004509 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304510 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4511 return dh.isFlowMonitoringRoutineActive[uniID]
4512 }
4513 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004514}
4515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004516func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304517 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004518
Maninder7961d722021-06-16 22:10:28 +05304519 connectStatus := voltha.ConnectStatus_UNREACHABLE
4520 operState := voltha.OperStatus_UNKNOWN
4521
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004522 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004523 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004524 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004525 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004526 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004527 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304528 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004529 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4530 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4531 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4532 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4533 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4534 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4535 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4536 // However, a later refactoring of the functionality remains unaffected.
4537 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004538 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004539 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304540 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004541 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304542 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004543 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004544 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304545 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004546 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4547 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304548 operState = voltha.OperStatus_ACTIVE
4549 } else {
4550 operState = voltha.OperStatus_ACTIVATING
4551 }
4552 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004553 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4554 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4555 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304556 operState = voltha.OperStatus_DISCOVERED
4557 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004558 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004559 logger.Debugw(ctx, "Core DeviceStateUpdate",
4560 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304561 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304562 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004563 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004564 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004565 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004566 ConnStatus: connectStatus,
4567 OperStatus: operState,
4568 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304569 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004570 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304571 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004572 } else {
Maninderb5187552021-03-23 22:23:42 +05304573 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004574 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004576 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304577 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004578 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004579 } else {
4580 onuDevEntry.MutexPersOnuConfig.RLock()
4581 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4582 connectStatus = voltha.ConnectStatus_REACHABLE
4583 }
4584 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304585 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004586 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004587 }
mpagenko101ac942021-11-16 15:01:29 +00004588 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004589 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004590 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004591 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004593 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304594 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004595 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004596 } else {
4597 onuDevEntry.MutexPersOnuConfig.RLock()
4598 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4599 connectStatus = voltha.ConnectStatus_REACHABLE
4600 }
4601 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304602 }
4603
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004604 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304605
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004606 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004607 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004608 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004609 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004610 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004611
4612 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4613 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4614 } else {
4615 onuDevEntry.MutexReconciledTpInstances.Lock()
4616 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4617 onuDevEntry.MutexReconciledTpInstances.Unlock()
4618 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004619 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004620 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004621 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304622 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004623 dh.reconciling = cSkipOnuConfigReconciling
4624 } else {
4625 dh.reconciling = cOnuConfigReconciling
4626 }
4627 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004628}
4629
mpagenko101ac942021-11-16 15:01:29 +00004630func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304631 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004632 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004633 dh.sendChReconcileFinished(success)
4634 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4635 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4636 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004637 } else {
mpagenko101ac942021-11-16 15:01:29 +00004638 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004639 }
4640}
4641
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004642func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004643 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004644 defer dh.mutexReconcilingFlag.RUnlock()
4645 return dh.reconciling != cNoReconciling
4646}
4647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004648func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004649 dh.mutexReconcilingFlag.RLock()
4650 defer dh.mutexReconcilingFlag.RUnlock()
4651 return dh.reconciling == cSkipOnuConfigReconciling
4652}
4653
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004654func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4655 dh.mutexReconcilingFirstPassFlag.Lock()
4656 dh.reconcilingFirstPass = value
4657 dh.mutexReconcilingFirstPassFlag.Unlock()
4658}
4659
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004660func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4661 dh.mutexReconcilingReasonUpdate.Lock()
4662 dh.reconcilingReasonUpdate = value
4663 dh.mutexReconcilingReasonUpdate.Unlock()
4664}
4665
4666func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4667 dh.mutexReconcilingReasonUpdate.RLock()
4668 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4669 return dh.reconcilingReasonUpdate
4670}
4671
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004672func (dh *deviceHandler) getDeviceReason() uint8 {
4673 dh.mutexDeviceReason.RLock()
4674 value := dh.deviceReason
4675 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004676 return value
4677}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004678
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004679func (dh *deviceHandler) GetDeviceReasonString() string {
4680 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004681}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004682
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004683func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004684 dh.mutexReadyForOmciConfig.Lock()
4685 dh.readyForOmciConfig = flagValue
4686 dh.mutexReadyForOmciConfig.Unlock()
4687}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004688func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004689 dh.mutexReadyForOmciConfig.RLock()
4690 flagValue := dh.readyForOmciConfig
4691 dh.mutexReadyForOmciConfig.RUnlock()
4692 return flagValue
4693}
Maninder7961d722021-06-16 22:10:28 +05304694
4695func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004696 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304697 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004698 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304699 }
4700
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004701 logger.Debugw(ctx, "Core DeviceStateUpdate",
4702 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004703 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004704 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004705 ConnStatus: connectStatus,
4706 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4707 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304708 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004709 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304710 }
4711}
khenaidoo7d3c5582021-08-11 18:09:44 -04004712
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304713func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4714 if techProfInstLoadFailed {
4715 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4716 logger.Errorw(ctx, "unable to update device reason to core",
4717 log.Fields{"device-id": dh.DeviceID, "Err": err})
4718 }
4719 context := make(map[string]string)
4720 context["device-id"] = dh.DeviceID
4721 context["onu-serial-number"] = dh.device.SerialNumber
4722 context["parent-id"] = dh.parentID
4723
4724 // Send event on flow configuration failure so that corrective action can be triggered from NB
4725 deviceEvent := &voltha.DeviceEvent{
4726 ResourceId: dh.DeviceID,
4727 DeviceEventName: cmn.OnuFlowConfigFailed,
4728 Description: cmn.OnuFlowConfigFailedDesc,
4729 Context: context,
4730 }
4731 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4732 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4733 }
4734}
4735
khenaidoo7d3c5582021-08-11 18:09:44 -04004736/*
4737Helper functions to communicate with Core
4738*/
4739
4740func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4741 cClient, err := dh.coreClient.GetCoreServiceClient()
4742 if err != nil || cClient == nil {
4743 return nil, err
4744 }
4745 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4746 defer cancel()
4747 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4748 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4749}
4750
khenaidoo42dcdfd2021-10-19 17:34:12 -04004751func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004752 cClient, err := dh.coreClient.GetCoreServiceClient()
4753 if err != nil || cClient == nil {
4754 return err
4755 }
4756 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4757 defer cancel()
4758 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004759 logger.Debugw(subCtx, "device-updated-in-core",
4760 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004761 return err
4762}
4763
4764func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4765 cClient, err := dh.coreClient.GetCoreServiceClient()
4766 if err != nil || cClient == nil {
4767 return err
4768 }
4769 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4770 defer cancel()
4771 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004772 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4773 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004774 return err
4775}
4776
4777func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4778 cClient, err := dh.coreClient.GetCoreServiceClient()
4779 if err != nil || cClient == nil {
4780 return err
4781 }
4782 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4783 defer cancel()
4784 _, err = cClient.DeviceUpdate(subCtx, device)
4785 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4786 return err
4787}
4788
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004789func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004790 cClient, err := dh.coreClient.GetCoreServiceClient()
4791 if err != nil || cClient == nil {
4792 return err
4793 }
4794 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4795 defer cancel()
4796 _, err = cClient.PortCreated(subCtx, port)
4797 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4798 return err
4799}
4800
khenaidoo42dcdfd2021-10-19 17:34:12 -04004801func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004802 cClient, err := dh.coreClient.GetCoreServiceClient()
4803 if err != nil || cClient == nil {
4804 return err
4805 }
4806 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4807 defer cancel()
4808 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004809 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 -04004810 return err
4811}
4812
khenaidoo42dcdfd2021-10-19 17:34:12 -04004813func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004814 cClient, err := dh.coreClient.GetCoreServiceClient()
4815 if err != nil || cClient == nil {
4816 return err
4817 }
4818 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4819 defer cancel()
4820 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004821 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 -04004822 return err
4823}
4824
4825/*
4826Helper functions to communicate with parent adapter
4827*/
4828
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004829func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4830 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4831
4832 var request = ia.TechProfileInstanceRequestMessage{
4833 DeviceId: dh.DeviceID,
4834 TpInstancePath: aTpPath,
4835 ParentDeviceId: dh.parentID,
4836 ParentPonPort: dh.device.ParentPortNo,
4837 OnuId: dh.device.ProxyAddress.OnuId,
4838 UniId: uint32(aUniID),
4839 }
4840
4841 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004842 if err != nil || pgClient == nil {
4843 return nil, err
4844 }
4845 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4846 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004847 logger.Debugw(subCtx, "get-tech-profile-instance",
4848 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004849 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004850}
4851
Girish Gowdrae95687a2021-09-08 16:30:58 -07004852// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4853// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4854func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4855 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4856 dh.setFlowMonitoringIsRunning(uniID, true)
4857 for {
4858 select {
4859 // block on the channel to receive an incoming flow
4860 // process the flow completely before proceeding to handle the next flow
4861 case flowCb := <-dh.flowCbChan[uniID]:
4862 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304863 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004864 respChan := make(chan error)
4865 if flowCb.addFlow {
4866 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4867 } else {
4868 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4869 }
4870 // Block on response and tunnel it back to the caller
4871 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304872 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004873 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4874 case <-dh.stopFlowMonitoringRoutine[uniID]:
4875 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4876 dh.setFlowMonitoringIsRunning(uniID, false)
4877 return
4878 }
4879 }
4880}
4881
kesavand011d5162021-11-25 19:21:06 +05304882func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4883 request.ParentDeviceId = dh.GetProxyAddressID()
4884 request.ChildDeviceId = dh.DeviceID
4885 request.ProxyAddress = dh.GetProxyAddress()
4886 request.ConnectStatus = common.ConnectStatus_REACHABLE
4887
4888 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4889 if err != nil || pgClient == nil {
4890 return err
4891 }
4892 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4893 defer cancel()
4894 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4895 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4896 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004897 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4898 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304899 }
4900 return err
4901}
4902
khenaidoo42dcdfd2021-10-19 17:34:12 -04004903func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004904 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4905 if err != nil || pgClient == nil {
4906 return err
4907 }
4908 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4909 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004910 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004911 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004912 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4913 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004914 if status.Code(err) == codes.Unavailable {
4915 dh.setOltAvailable(false)
4916 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004917 logger.Errorw(ctx, "omci-failure",
4918 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004919 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004920 }
4921 return err
4922}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004923
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004924func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4925 // Check if there are additional TCONT instances necessary/available
4926 pDevEntry.MutexPersOnuConfig.Lock()
4927 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4928 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4929 pDevEntry.MutexPersOnuConfig.Unlock()
4930 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4931 logger.Debugw(ctx, "checking available TCONT instances",
4932 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4933 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4934 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4935 log.Fields{"device-id": dh.device.Id})
4936 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304937 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004938 }
4939 } else {
4940 pDevEntry.MutexPersOnuConfig.Unlock()
4941 }
4942 // Check if there are enough PrioQueue instances available
4943 if dh.pOnuTP != nil {
4944 var numberOfUsPrioQueueDbInsts int
4945
4946 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4947 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304948 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004949 numberOfUsPrioQueueDbInsts++
4950 }
4951 }
4952 // Check if there is an upstream PriorityQueue instance available for each Gem port
4953 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4954 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4955 log.Fields{"device-id": dh.DeviceID,
4956 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4957 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4958 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4959
4960 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4961 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4962 log.Fields{"device-id": dh.device.Id})
4963 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304964 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 +00004965 }
4966 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4967 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4968 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4969 } else {
4970 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4971 log.Fields{"device-id": dh.DeviceID})
4972 }
4973 return nil
4974}
4975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004976// GetDeviceID - TODO: add comment
4977func (dh *deviceHandler) GetDeviceID() string {
4978 return dh.DeviceID
4979}
4980
4981// GetProxyAddressID - TODO: add comment
4982func (dh *deviceHandler) GetProxyAddressID() string {
4983 return dh.device.ProxyAddress.GetDeviceId()
4984}
4985
4986// GetProxyAddressType - TODO: add comment
4987func (dh *deviceHandler) GetProxyAddressType() string {
4988 return dh.device.ProxyAddress.GetDeviceType()
4989}
4990
4991// GetProxyAddress - TODO: add comment
4992func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4993 return dh.device.ProxyAddress
4994}
4995
4996// GetEventProxy - TODO: add comment
4997func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4998 return dh.EventProxy
4999}
5000
5001// GetOmciTimeout - TODO: add comment
5002func (dh *deviceHandler) GetOmciTimeout() int {
5003 return dh.pOpenOnuAc.omciTimeout
5004}
5005
5006// GetAlarmAuditInterval - TODO: add comment
5007func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5008 return dh.pOpenOnuAc.alarmAuditInterval
5009}
5010
5011// GetDlToOnuTimeout4M - TODO: add comment
5012func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5013 return dh.pOpenOnuAc.dlToOnuTimeout4M
5014}
5015
5016// GetUniEntityMap - TODO: add comment
5017func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5018 return &dh.uniEntityMap
5019}
5020
5021// GetPonPortNumber - TODO: add comment
5022func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5023 return &dh.ponPortNumber
5024}
5025
5026// GetUniVlanConfigFsm - TODO: add comment
5027func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005028 dh.lockVlanConfig.RLock()
5029 value := dh.UniVlanConfigFsmMap[uniID]
5030 dh.lockVlanConfig.RUnlock()
5031 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005032}
5033
5034// GetOnuAlarmManager - TODO: add comment
5035func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5036 return dh.pAlarmMgr
5037}
5038
5039// GetOnuMetricsManager - TODO: add comment
5040func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5041 return dh.pOnuMetricsMgr
5042}
5043
5044// GetOnuTP - TODO: add comment
5045func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5046 return dh.pOnuTP
5047}
5048
5049// GetBackendPathPrefix - TODO: add comment
5050func (dh *deviceHandler) GetBackendPathPrefix() string {
5051 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5052}
5053
5054// GetOnuIndication - TODO: add comment
5055func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
5056 return dh.pOnuIndication
5057}
5058
5059// RLockMutexDeletionInProgressFlag - TODO: add comment
5060func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5061 dh.mutexDeletionInProgressFlag.RLock()
5062}
5063
5064// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5065func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5066 dh.mutexDeletionInProgressFlag.RUnlock()
5067}
5068
5069// GetDeletionInProgress - TODO: add comment
5070func (dh *deviceHandler) GetDeletionInProgress() bool {
5071 return dh.deletionInProgress
5072}
5073
5074// GetPmConfigs - TODO: add comment
5075func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5076 return dh.pmConfigs
5077}
5078
5079// GetDeviceType - TODO: add comment
5080func (dh *deviceHandler) GetDeviceType() string {
5081 return dh.DeviceType
5082}
5083
5084// GetLogicalDeviceID - TODO: add comment
5085func (dh *deviceHandler) GetLogicalDeviceID() string {
5086 return dh.logicalDeviceID
5087}
5088
5089// GetDevice - TODO: add comment
5090func (dh *deviceHandler) GetDevice() *voltha.Device {
5091 return dh.device
5092}
5093
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005094func (dh *deviceHandler) setOltAvailable(value bool) {
5095 dh.mutexOltAvailable.Lock()
5096 dh.oltAvailable = value
5097 dh.mutexOltAvailable.Unlock()
5098}
5099
5100// IsOltAvailable - TODO: add comment
5101func (dh *deviceHandler) IsOltAvailable() bool {
5102 dh.mutexOltAvailable.RLock()
5103 defer dh.mutexOltAvailable.RUnlock()
5104 return dh.oltAvailable
5105}
5106
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005107// GetMetricsEnabled - TODO: add comment
5108func (dh *deviceHandler) GetMetricsEnabled() bool {
5109 return dh.pOpenOnuAc.MetricsEnabled
5110}
5111
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005112// GetExtendedOmciSupportEnabled - TODO: add comment
5113func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5114 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5115}
5116
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305117// GetExtendedOmciSupportEnabled - TODO: add comment
5118func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5119 return dh.pOpenOnuAc.skipOnuConfig
5120}
5121
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305122func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5123 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5124}
5125
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005126// InitPmConfigs - TODO: add comment
5127func (dh *deviceHandler) InitPmConfigs() {
5128 dh.pmConfigs = &voltha.PmConfigs{}
5129}
5130
5131// GetUniPortMask - TODO: add comment
5132func (dh *deviceHandler) GetUniPortMask() int {
5133 return dh.pOpenOnuAc.config.UniPortMask
5134}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005135
5136func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5137 tpPathFound := false
5138 for _, tpPath := range aTpPathMap {
5139 if tpPath != "" {
5140 tpPathFound = true
5141 }
5142 }
5143 return tpPathFound
5144}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005145
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305146func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5147 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5148 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5149 return resp
5150}
5151
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305152// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5153func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5154 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
5155 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5156 return resp
5157}
5158
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305159func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5160 return dh.deviceDeleteCommChan
5161}
5162
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005163// PrepareForGarbageCollection - remove references to prepare for garbage collection
5164func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5165 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5166
5167 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5168 // first let the objects rest for some time to give all asynchronously started
5169 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005170 time.Sleep(2 * time.Second)
5171
5172 if dh.pOnuOmciDevice != nil {
5173 if dh.pOnuOmciDevice.PDevOmciCC != nil {
5174 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
5175 // reset handling (even in future coding), request monitoring is canceled here one last time to
5176 // be sure that all corresponding go routines are terminated
5177 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
5178 }
5179 }
5180 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005181
5182 if dh.pOnuTP != nil {
5183 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5184 }
5185 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005186 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5187 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005188 select {
5189 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5190 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5191 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5192 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005193 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005194 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005195 }
5196 if dh.pAlarmMgr != nil {
5197 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5198 }
5199 if dh.pSelfTestHdlr != nil {
5200 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5201 }
5202 if dh.pLockStateFsm != nil {
5203 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5204 }
5205 if dh.pUnlockStateFsm != nil {
5206 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5207 }
5208 if dh.pOnuUpradeFsm != nil {
5209 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5210 }
5211 if dh.pOnuOmciDevice != nil {
5212 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5213 }
5214 for k, v := range dh.UniVlanConfigFsmMap {
5215 v.PrepareForGarbageCollection(ctx, aDeviceID)
5216 delete(dh.UniVlanConfigFsmMap, k)
5217 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305218 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005219 dh.pOnuOmciDevice = nil
5220 dh.pOnuTP = nil
5221 dh.pOnuMetricsMgr = nil
5222 dh.pAlarmMgr = nil
5223 dh.pSelfTestHdlr = nil
5224 dh.pLockStateFsm = nil
5225 dh.pUnlockStateFsm = nil
5226 dh.pOnuUpradeFsm = nil
5227}