blob: b18500334f95a8606ab9c33cba420fa39ff8b94d [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo42dcdfd2021-10-19 17:34:12 -040050 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040051 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
52 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000053 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040054 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000055 "google.golang.org/grpc/codes"
56 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057)
58
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059const (
mpagenko101ac942021-11-16 15:01:29 +000060 //constants for reconcile flow check channel
61 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
62 cWaitReconcileFlowAbortOnError = 0xFFFE
63 cWaitReconcileFlowNoActivity = 0xFFFF
64)
65
66const (
67 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000068 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070
mpagenko1cc3cb42020-07-27 15:24:38 +000071const (
mpagenko44bd8362021-11-15 11:40:05 +000072 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
73 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
74 // as long as such is not available by the libraries - use this workaround
75 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
76)
77
78const (
mpagenko1cc3cb42020-07-27 15:24:38 +000079 // events of Device FSM
80 devEvDeviceInit = "devEvDeviceInit"
81 devEvGrpcConnected = "devEvGrpcConnected"
82 devEvGrpcDisconnected = "devEvGrpcDisconnected"
83 devEvDeviceUpInd = "devEvDeviceUpInd"
84 devEvDeviceDownInd = "devEvDeviceDownInd"
85)
86const (
87 // states of Device FSM
88 devStNull = "devStNull"
89 devStDown = "devStDown"
90 devStInit = "devStInit"
91 devStConnected = "devStConnected"
92 devStUp = "devStUp"
93)
94
praneeth nalmas5a0a5502022-12-23 15:57:00 +053095// Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096const (
Himani Chawla4d908332020-08-31 12:30:20 +053097 pon = voltha.EventSubCategory_PON
98 //olt = voltha.EventSubCategory_OLT
99 //ont = voltha.EventSubCategory_ONT
100 //onu = voltha.EventSubCategory_ONU
101 //nni = voltha.EventSubCategory_NNI
102 //service = voltha.EventCategory_SERVICE
103 //security = voltha.EventCategory_SECURITY
104 equipment = voltha.EventCategory_EQUIPMENT
105 //processing = voltha.EventCategory_PROCESSING
106 //environment = voltha.EventCategory_ENVIRONMENT
107 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000108)
109
110const (
111 cEventObjectType = "ONU"
112)
113const (
114 cOnuActivatedEvent = "ONU_ACTIVATED"
115)
116
mpagenkof1fc3862021-02-16 10:09:52 +0000117type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000119 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000122var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
123 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
124 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
125 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
128 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
129 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
130 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000131}
132
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000133const (
134 cNoReconciling = iota
135 cOnuConfigReconciling
136 cSkipOnuConfigReconciling
137)
138
Girish Gowdrae95687a2021-09-08 16:30:58 -0700139// FlowCb is the flow control block containing flow add/delete information along with a response channel
140type FlowCb struct {
141 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142 flowItem *of.OfpFlowStats
143 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400144 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 respChan *chan error // channel to report the Flow handling error
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530146 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147}
148
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530149// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530151 EventProxy eventif.EventProxy
152
153 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000154
khenaidoo7d3c5582021-08-11 18:09:44 -0400155 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000156
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800157 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400158 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800159
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160 pOpenOnuAc *OpenONUAC
161 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530162 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530163 deviceEntrySet chan bool //channel for DeviceEntry set event
164 pOnuOmciDevice *mib.OnuDeviceEntry
165 pOnuTP *avcfg.OnuUniTechProf
166 pOnuMetricsMgr *pmmgr.OnuMetricsManager
167 pAlarmMgr *almgr.OnuAlarmManager
168 pSelfTestHdlr *otst.SelfTestControlBlock
169 exitChannel chan int
170 pOnuIndication *oop.OnuIndication
171 pLockStateFsm *uniprt.LockStateFsm
172 pUnlockStateFsm *uniprt.LockStateFsm
173
174 stopCollector chan bool
175 stopAlarmManager chan bool
176 stopHeartbeatCheck chan bool
177 uniEntityMap cmn.OnuUniPortMap
178 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
179 pOnuUpradeFsm *swupg.OnuUpgradeFsm
180 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530181 chUniVlanConfigOnRebootDone chan uint16
182 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530183 pLastUpgradeImageState *voltha.ImageState
184 upgradeFsmChan chan struct{}
185
186 deviceDeleteCommChan chan bool
187 DeviceID string
188 DeviceType string
189 adminState string
190 logicalDeviceID string
191 ProxyAddressID string
192 ProxyAddressType string
193 parentID string
194
195 flowCbChan []chan FlowCb
196 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
197 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
198 reconcileExpiryComplete time.Duration
199 reconcileExpiryVlanConfig time.Duration
200 lockDevice sync.RWMutex
201 mutexDeviceReason sync.RWMutex
202 mutexCollectorFlag sync.RWMutex
203 mutextAlarmManagerFlag sync.RWMutex
204 lockVlanConfig sync.RWMutex
205 lockVlanAdd sync.RWMutex
206 lockUpgradeFsm sync.RWMutex
207 mutexReconcilingFlag sync.RWMutex
208 mutexReconcilingFirstPassFlag sync.RWMutex
209 mutexReconcilingReasonUpdate sync.RWMutex
210 mutexReadyForOmciConfig sync.RWMutex
211 mutexDeletionInProgressFlag sync.RWMutex
212 mutexFlowMonitoringRoutineFlag sync.RWMutex
213 mutexForDisableDeviceRequested sync.RWMutex
214 mutexOltAvailable sync.RWMutex
215 mutexKvStoreContext sync.Mutex
216 ponPortNumber uint32
217
218 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000219
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000220 //flowMgr *OpenOltFlowMgr
221 //eventMgr *OpenOltEventMgr
222 //resourceMgr *rsrcMgr.OpenOltResourceMgr
223
224 //discOnus sync.Map
225 //onus sync.Map
226 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530227 collectorIsRunning bool
228 alarmManagerIsRunning bool
229 upgradeCanceled bool
230 reconciling uint8
231 reconcilingFirstPass bool
232 reconcilingReasonUpdate bool
233 readyForOmciConfig bool
234 deletionInProgress bool
235 disableDeviceRequested bool // this flag identify ONU received disable request or not
236 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530239// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400240func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400242 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400244 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.DeviceType = cloned.Type
248 dh.adminState = "up"
249 dh.device = cloned
250 dh.pOpenOnuAc = adapter
251 dh.exitChannel = make(chan int, 1)
252 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000253 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000254 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530256 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530257 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopHeartbeatCheck = make(chan bool, 2)
259 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000261 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000262 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000263 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000264 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300265 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000266 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000267 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000268 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000269 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300270 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000271 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000272 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000273 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
274 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
275 if rECSeconds < 2 {
276 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
277 rECSeconds = 2
278 }
279 rEVCSeconds := rECSeconds / 2
280 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000281 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000282 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000283 dh.pLastUpgradeImageState = &voltha.ImageState{
284 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
285 Reason: voltha.ImageState_UNKNOWN_ERROR,
286 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
287 }
288 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530289 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800291 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
292 dh.pmConfigs = cloned.PmConfigs
293 } /* else {
294 // will be populated when onu_metrics_mananger is initialized.
295 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800296
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 // Device related state machine
298 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000301 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
302 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
303 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
304 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
305 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 },
307 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000308 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
309 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
310 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
311 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
312 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
313 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
314 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
315 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 },
317 )
mpagenkoaf801632020-07-03 10:00:42 +0000318
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 return &dh
320}
321
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322// start save the device to the data model
323func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000324 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000326 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327}
328
Himani Chawla4d908332020-08-31 12:30:20 +0530329/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530331func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332 logger.Debug("stopping-device-handler")
333 dh.exitChannel <- 1
334}
Himani Chawla4d908332020-08-31 12:30:20 +0530335*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000336
337// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530338// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530340// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530341func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400342 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000344 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530345
mpagenko1cc3cb42020-07-27 15:24:38 +0000346 if dh.pDeviceStateFsm.Is(devStNull) {
347 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000348 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000349 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000350 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800351 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
352 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800353 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400354 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000355 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800356 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800357 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000358 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360 }
361
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000362}
363
khenaidoo42dcdfd2021-10-19 17:34:12 -0400364func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000365 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530366 //assuming omci message content is hex coded!
367 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000370 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000373 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000375 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000376 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
377 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
380 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530381}
382
khenaidoo42dcdfd2021-10-19 17:34:12 -0400383func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000385
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
389 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 if dh.pOnuTP == nil {
392 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000393 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000394 log.Fields{"device-id": dh.DeviceID})
395 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000397 if !dh.IsReadyForOmciConfig() {
398 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
399 "device-state": dh.GetDeviceReasonString()})
400 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000402 //previous state test here was just this one, now extended for more states to reject the SetRequest:
403 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
404 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530405
Himani Chawla26e555c2020-08-31 12:30:20 +0530406 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000407 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
408 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000409 dh.pOnuTP.LockTpProcMutex()
410 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411
mpagenko44bd8362021-11-15 11:40:05 +0000412 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530413 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
414 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415 }
416 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000417 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800418 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000419 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
420 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800421 return err
422 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000423 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
424 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000426 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530427
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400429 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000430 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
431 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000432
433 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
434 if err != nil {
435 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
436 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
437 // stopping all further processing
438 _ = dh.UpdateInterface(ctx)
439 return err
440 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700441 // if there has been some change for some uni TechProfilePath
442 //in order to allow concurrent calls to other dh instances we do not wait for execution here
443 //but doing so we can not indicate problems to the caller (who does what with that then?)
444 //by now we just assume straightforward successful execution
445 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
446 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530447
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 // deadline context to ensure completion of background routines waited for
449 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
450 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
451 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000453 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700454
455 var wg sync.WaitGroup
456 wg.Add(1) // for the 1 go routine to finish
457 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700459 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
461 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 return tpErr
463 }
464 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
465 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530466 defer cancel2()
467 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
468 if err1 != nil {
469 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
470 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700471 }
472 return nil
473 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000474 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700475 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700476 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000479 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
480 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 return nil
482}
483
khenaidoo42dcdfd2021-10-19 17:34:12 -0400484func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000485 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530486
487 if dh.pOnuTP == nil {
488 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 log.Fields{"device-id": dh.DeviceID})
491 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000494 dh.pOnuTP.LockTpProcMutex()
495 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530496
mpagenko0f543222021-11-03 16:24:14 +0000497 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
498 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
499 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530500 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
501 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502 }
503 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000504 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000506 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
507 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 return err
509 }
mpagenko0f543222021-11-03 16:24:14 +0000510 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
511 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000512 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
Mahir Gunyel9545be22021-07-04 15:53:16 -0700514 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000515 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
Himani Chawla26e555c2020-08-31 12:30:20 +0530517}
518
khenaidoo42dcdfd2021-10-19 17:34:12 -0400519func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000520 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 +0000521
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
525 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 if dh.pOnuTP == nil {
528 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000529 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000530 log.Fields{"device-id": dh.DeviceID})
531 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 }
533
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 dh.pOnuTP.LockTpProcMutex()
536 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537
mpagenko0f543222021-11-03 16:24:14 +0000538 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
539 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
540 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530541 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
542 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000543 }
544 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700545 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800547 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000548 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
549 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800550 return err
551 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530553
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000554 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
555 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530556 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000557 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 +0530558 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
559 if err1 != nil {
560 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
561 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000562 }
563
Mahir Gunyel9545be22021-07-04 15:53:16 -0700564 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000566
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000568
Mahir Gunyel9545be22021-07-04 15:53:16 -0700569func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
571 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
574 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530575 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 resourceName = "Gem"
579 } else {
580 resourceName = "Tcont"
581 }
582
583 // deadline context to ensure completion of background routines waited for
584 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
585 dctx, cancel := context.WithDeadline(context.Background(), deadline)
586
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700588
589 var wg sync.WaitGroup
590 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700592 resource, entryID, &wg)
593 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
595 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700596 return err
597 }
598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000599 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
600 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
601 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
602 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700603 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530604 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700605 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000606 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 +0530607 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
608 if err != nil {
609 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700610 return err
611 }
612 }
613 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000614 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700615 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530616 return nil
617}
618
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530619// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400621 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400622 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700623 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
624 var errorsList []error
625 var retError error
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530626 if dh.GetPersRebootFlag(ctx) {
627 logger.Warnw(ctx, "FlowUpdateIncremental ignored as deivce is being configured post reboot", log.Fields{"device-id": dh.DeviceID})
628 return fmt.Errorf("errors-installing-one-or-more-flows-groups-reboot-in-progress")
629 }
mpagenko01e726e2020-10-23 09:45:29 +0000630 //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 +0000631 if apOfFlowChanges.ToRemove != nil {
632 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000633 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000635 "device-id": dh.DeviceID})
636 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700637 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000638 continue
639 }
640 flowInPort := flow.GetInPort(flowItem)
641 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
643 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700644 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000645 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000647 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000648 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000651 continue
652 } else {
653 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000654 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000655 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
656 loUniPort = uniPort
657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000660 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700662 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000663 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000664 }
665 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
668 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700669
670 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
671 // Step1 : Fill flowControlBlock
672 // Step2 : Push the flowControlBlock to ONU channel
673 // Step3 : Wait on response channel for response
674 // Step4 : Return error value
675 startTime := time.Now()
676 respChan := make(chan error)
677 flowCb := FlowCb{
678 ctx: ctx,
679 addFlow: false,
680 flowItem: flowItem,
681 flowMetaData: nil,
682 uniPort: loUniPort,
683 respChan: &respChan,
684 }
685 dh.flowCbChan[loUniPort.UniID] <- flowCb
686 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
687 // Wait on the channel for flow handlers return value
688 retError = <-respChan
689 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
690 if retError != nil {
691 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
692 log.Fields{"device-id": dh.DeviceID, "error": retError})
693 errorsList = append(errorsList, retError)
694 continue
695 }
696 } else {
697 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
698 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000699 }
700 }
701 }
702 }
mpagenko01e726e2020-10-23 09:45:29 +0000703 if apOfFlowChanges.ToAdd != nil {
704 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
705 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000707 "device-id": dh.DeviceID})
708 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700709 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000710 continue
711 }
712 flowInPort := flow.GetInPort(flowItem)
713 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
715 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700716 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000717 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000718 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000719 } else if flowInPort == dh.ponPortNumber {
720 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000722 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000723 continue
724 } else {
725 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000726 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000727 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
728 loUniPort = uniPort
729 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000732 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000733 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700734 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000735 continue
mpagenko01e726e2020-10-23 09:45:29 +0000736 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000737 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
738 // if not, we just throw some error here to have an indication about that, if we really need to support that
739 // then we would need to create some means to activate the internal stored flows
740 // after the device gets active automatically (and still with its dependency to the TechProfile)
741 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
742 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000743 if !dh.IsReadyForOmciConfig() {
744 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
745 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700746 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
747 errorsList = append(errorsList, retError)
748 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 }
750
mpagenko01e726e2020-10-23 09:45:29 +0000751 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000753 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
754 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700755 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
756 // Step1 : Fill flowControlBlock
757 // Step2 : Push the flowControlBlock to ONU channel
758 // Step3 : Wait on response channel for response
759 // Step4 : Return error value
760 startTime := time.Now()
761 respChan := make(chan error)
762 flowCb := FlowCb{
763 ctx: ctx,
764 addFlow: true,
765 flowItem: flowItem,
766 flowMetaData: apFlowMetaData,
767 uniPort: loUniPort,
768 respChan: &respChan,
769 }
770 dh.flowCbChan[loUniPort.UniID] <- flowCb
771 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
772 // Wait on the channel for flow handlers return value
773 retError = <-respChan
774 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
775 if retError != nil {
776 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
777 log.Fields{"device-id": dh.DeviceID, "error": retError})
778 errorsList = append(errorsList, retError)
779 continue
780 }
781 } else {
782 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
783 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000784 }
785 }
786 }
787 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700788 if len(errorsList) > 0 {
789 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
790 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
791 }
792 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000793}
794
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530795// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
796// following are the expected device states after this activity:
797// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000798// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
800 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300801 dh.mutexForDisableDeviceRequested.Lock()
802 dh.disableDeviceRequested = true
803 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000804 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000805 //note that disableDevice sequences in some 'ONU active' state may yield also
806 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000807 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000809 //disable-device shall be just a UNi/ONU-G related admin state setting
810 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000811
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000813 // disable UNI ports/ONU
814 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
815 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000816 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000817 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000820 }
821 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000822 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000824 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400825 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000827 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400828 OperStatus: voltha.OperStatus_UNKNOWN,
829 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000830 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000832 }
mpagenko01e726e2020-10-23 09:45:29 +0000833 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000834
835 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000836 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000837 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300838 }
839}
840
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530841// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
843 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000844
mpagenkoaa3afe92021-05-21 16:20:58 +0000845 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000846 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
847 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
848 // for real ONU's that should have nearly no influence
849 // Note that for real ONU's there is anyway a problematic situation with following sequence:
850 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
851 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
852 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000854
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000855 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300857 dh.mutexForDisableDeviceRequested.Lock()
858 dh.disableDeviceRequested = false
859 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000860 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000862 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000865 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300866}
867
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530869 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 return
875 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000877 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000879 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000881 }
mpagenko101ac942021-11-16 15:01:29 +0000882 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000883 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000884 }
Himani Chawla4d908332020-08-31 12:30:20 +0530885 var onuIndication oop.OnuIndication
akashreddykb03dde02025-12-02 10:53:18 +0530886 var rebootInProgress bool
887 var persUniUnlockDone bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 pDevEntry.MutexPersOnuConfig.RLock()
889 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
890 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
891 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
892 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
akashreddykb03dde02025-12-02 10:53:18 +0530893 rebootInProgress = pDevEntry.SOnuPersistentData.PersRebootInProgress
894 persUniUnlockDone = pDevEntry.SOnuPersistentData.PersUniUnlockDone
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000895 pDevEntry.MutexPersOnuConfig.RUnlock()
akashreddykb03dde02025-12-02 10:53:18 +0530896 if rebootInProgress {
897 if persUniUnlockDone {
898 logger.Warnw(ctx, "ONU indication shows reboot in progress - cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID})
899 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
900 return
901 }
902 }
903 if onuIndication.OperState == "up" {
904 if err := dh.createInterface(ctx, &onuIndication); err != nil {
905 logger.Errorw(ctx, "failed to handle device up indication", log.Fields{"device-id": dh.DeviceID, "error": err})
906 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
907 return
908 }
909 } else {
910 logger.Warnw(ctx, "ONU indication does not have 'up' state, cannot proceed with reconciliation", log.Fields{"device-id": dh.DeviceID, "operState": onuIndication.OperState})
911 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
912 return
913 }
914 logger.Debugw(ctx, "reconciling - simulate onu indication done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000915}
916
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000917func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530918 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000919
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000920 continueWithFlowConfig := false
921
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000922 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000923 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000924 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000925 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
926 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 dh.pOnuTP.LockTpProcMutex()
929 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000930
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000931 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000932 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
934 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530935 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000936 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000937 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
938 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000939 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000940 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700941 techProfsFound := false
942 techProfInstLoadFailed := false
943outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000944 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000945 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000946 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000947 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000948 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000949 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000950 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000951 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
953 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000954 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000956 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700957 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000958 var iaTechTpInst ia.TechProfileDownloadMessage
959 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000961 pDevEntry.MutexReconciledTpInstances.RLock()
962 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
963 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000964 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000965 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700966 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000967 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700968 break outerLoop
969 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000970 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000971 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700972 var tpInst tech_profile.TechProfileInstance
973 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400974 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700975 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000976 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700978 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000979 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700981 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
982 break outerLoop
983 }
984
Girish Gowdra041dcb32020-11-16 16:54:30 -0800985 // deadline context to ensure completion of background routines waited for
986 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
987 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000988 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000989
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800991 var wg sync.WaitGroup
992 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000995 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
996 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700997 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
998 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800999 }
mpagenko2dc896e2021-08-02 12:03:59 +00001000 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 if len(uniData.PersFlowParams) != 0 {
1002 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001003 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001004 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +00001005 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001006 } // for all UNI entries from SOnuPersistentData
1007 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
1008 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001009 }
mpagenko2dc896e2021-08-02 12:03:59 +00001010
1011 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
1012 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001013
1014 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +00001015}
1016
1017func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
1018 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
1019 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301020 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001021 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001022 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023 return
1024 }
mpagenko2dc896e2021-08-02 12:03:59 +00001025 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001026 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001027 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001028 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001030 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001031 }
mpagenko2dc896e2021-08-02 12:03:59 +00001032 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301033 logger.Warn(ctx, "reconciling - no flows 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 Hildebrandtbe523842021-03-10 10:47:18 +00001036 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001037}
1038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1040 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001041
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001043 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001044 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001045 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001046 return
1047 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001048
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 pDevEntry.MutexPersOnuConfig.RLock()
1050 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1051 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301052 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001054 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001055 return
1056 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001057 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001058 var uniVlanConfigEntries []uint8
1059 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001061 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001062 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1063 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001064 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001066 continue
1067 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001068 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001069 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001071 // It doesn't make sense to configure any flows if no TPs are available
1072 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001073 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1075 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001076 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001077 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001078
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001080 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001081 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001082 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001083 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1084 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001085 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001086 return
1087 }
mpagenko101ac942021-11-16 15:01:29 +00001088 //needed to split up function due to sca complexity
1089 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1090
mpagenko2dc896e2021-08-02 12:03:59 +00001091 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001092 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001093 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1094 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001095 // this can't be used as global finished reconciling flag because
1096 // assumes is getting called before the state machines for the last flow is completed,
1097 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001098 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1099 } // for all UNI entries from SOnuPersistentData
1100 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001101
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001102 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301103 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001105 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001106 return
1107 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001108 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1109 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1110 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1111 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1112 log.Fields{"device-id": dh.DeviceID})
1113 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1114 if pDevEntry != nil {
1115 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001116 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001117 } else {
1118 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1119 log.Fields{"device-id": dh.DeviceID})
1120 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1121 if pDevEntry != nil {
1122 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1123 }
1124 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001125 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001126 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001127}
1128
mpagenko101ac942021-11-16 15:01:29 +00001129func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1130 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1131 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1132 flowsProcessed := 0
1133 lastFlowToReconcile := false
1134 loUniID := apUniPort.UniID
1135 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001136 if !(*apFlowsFound) {
1137 *apFlowsFound = true
1138 syncChannel := make(chan struct{})
1139 // start go routine with select() on reconciling vlan config channel before
1140 // starting vlan config reconciling process to prevent loss of any signal
1141 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1142 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1143 //block until the wait routine is really blocked on channel input
1144 // in order to prevent to early ready signal from VlanConfig processing
1145 <-syncChannel
1146 }
1147 if flowsProcessed == len(aPersFlowParam)-1 {
1148 var uniAdded bool
1149 lastFlowToReconcile = true
1150 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1151 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001152 }
1153 }
mpagenko101ac942021-11-16 15:01:29 +00001154 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1155 "device-id": dh.DeviceID, "uni-id": loUniID,
1156 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1157 dh.lockVlanConfig.Lock()
1158 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1159 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1160 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301161 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 +00001162 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1163 }
1164 } else {
1165 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301166 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301167 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001168 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1169 }
1170 }
1171 dh.lockVlanConfig.Unlock()
1172 flowsProcessed++
1173 } //for all flows of this UNI
1174}
1175
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301176// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1177//
1178// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001179func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1180 waitGroup *cmn.WaitGroupWithTimeOut) {
1181 var reconciledUniVlanConfigEntries []uint8
1182 var appended bool
1183 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1184 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1185 "device-id": dh.DeviceID, "expiry": expiry})
1186 // indicate blocking on channel now to the caller
1187 aSyncChannel <- struct{}{}
1188 for {
1189 select {
1190 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1191 switch uniIndication {
1192 // no activity requested (should normally not be received) - just continue waiting
1193 case cWaitReconcileFlowNoActivity:
1194 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1195 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301196 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001197 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1198 return
1199 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1200 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301201 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001202 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1203 return
1204 // this should be a valid UNI vlan config done indication
1205 default:
1206 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301207 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001208 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1209 if reconciledUniVlanConfigEntries, appended =
1210 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1211 waitGroup.Done()
1212 }
1213 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301214 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 +00001215 }
1216 } //switch uniIndication
1217
1218 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1219 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1220 log.Fields{"device-id": dh.DeviceID})
1221 return
1222 }
1223 }
1224}
1225
1226func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1227 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1228}
1229
1230func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1231 for _, ele := range slice {
1232 if ele == val {
1233 return slice, false
1234 }
1235 }
1236 return append(slice, val), true
1237}
1238
1239// sendChReconcileFinished - sends true or false on reconcileFinish channel
1240func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1241 if dh != nil { //if the object still exists (might have been already deleted in background)
1242 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1243 select {
1244 case dh.chReconcilingFinished <- success:
1245 default:
1246 }
1247 }
1248}
1249
1250// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1251func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1252 if dh != nil { //if the object still exists (might have been already deleted in background)
1253 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1254 select {
1255 case dh.chUniVlanConfigReconcilingDone <- value:
1256 default:
1257 }
1258 }
1259}
1260
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301261func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1262 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1263
1264 defer dh.UpdateAndStoreRebootState(ctx, false)
1265 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1266 if pDevEntry == nil {
1267 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1268 return
1269 }
1270
1271 pDevEntry.MutexPersOnuConfig.RLock()
1272 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1273 pDevEntry.MutexPersOnuConfig.RUnlock()
1274 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1275 log.Fields{"device-id": dh.DeviceID})
1276 return
1277 }
1278 flowsFound := false
1279 var uniVlanConfigEntries []uint8
1280 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1281
1282 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1283 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1284 if len(uniData.PersFlowParams) == 0 {
1285 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1286 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1287 continue
1288 }
1289 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1290 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1291 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1292 // It doesn't make sense to configure any flows if no TPs are available
1293 continue
1294 }
1295 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1296 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1297 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1298 pDevEntry.MutexPersOnuConfig.RUnlock()
1299
1300 var uniPort *cmn.OnuUniPort
1301 var exist bool
1302 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1303 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1304 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1305 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1306 return
1307 }
1308
1309 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1310
1311 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1312 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1313 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1314 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1315 // this can't be used as global finished reconciling flag because
1316 // assumes is getting called before the state machines for the last flow is completed,
1317 // while this is not guaranteed.
1318 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1319 } // for all UNI entries from SOnuPersistentData
1320 pDevEntry.MutexPersOnuConfig.RUnlock()
1321
1322 if !flowsFound {
1323 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1324 log.Fields{"device-id": dh.DeviceID})
1325 return
1326 }
1327 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1328 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1329 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1330 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1331 log.Fields{"device-id": dh.DeviceID})
1332 } else {
1333 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1334 log.Fields{"device-id": dh.DeviceID})
1335 return
1336 }
1337}
1338
1339func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1340 dh.UpdateRebootPersData(ctx, flag)
1341 if err := dh.StorePersistentData(ctx); err != nil {
1342 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1343 }
1344}
1345
1346func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1347 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1348 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1349 flowsProcessed := 0
1350 lastFlowToConfigOnReboot := false
1351 loUniID := apUniPort.UniID
1352 for _, flowData := range aPersFlowParam {
1353 if !(*apFlowsFound) {
1354 *apFlowsFound = true
1355 syncChannel := make(chan struct{})
1356 // start go routine with select() on reconciling vlan config channel before
1357 // starting vlan config reconciling process to prevent loss of any signal
1358 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1359 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1360 //block until the wait routine is really blocked on channel input
1361 // in order to prevent to early ready signal from VlanConfig processing
1362 <-syncChannel
1363 }
1364 if flowsProcessed == len(aPersFlowParam)-1 {
1365 var uniAdded bool
1366 lastFlowToConfigOnReboot = true
1367 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1368 apWaitGroup.Add(1) //increment the waiting group
1369 }
1370 }
1371 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1372 "device-id": dh.DeviceID, "uni-id": loUniID,
1373 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1374 dh.lockVlanConfig.Lock()
1375 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1376 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1377 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1378 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 {
1379 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1380 }
1381 } else {
1382 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1383 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1384 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1385 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1386 }
1387 }
1388 dh.lockVlanConfig.Unlock()
1389 flowsProcessed++
1390 } //for all flows of this UNI
1391}
1392
1393func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1394 waitGroup *cmn.WaitGroupWithTimeOut) {
1395 var rebootUniVlanConfigEntries []uint8
1396 var appended bool
1397 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1398 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1399 "device-id": dh.DeviceID, "expiry": expiry})
1400 // indicate blocking on channel now to the caller
1401 aSyncChannel <- struct{}{}
1402 for {
1403 select {
1404 case <-dh.deviceDeleteCommChan:
1405 // Cancel the context and return
1406 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1407 return
1408
1409 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1410 switch uniIndication {
1411 // this should be a valid UNI vlan config done indication
1412 default:
1413 if uniIndication < platform.MaxUnisPerOnu {
1414 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1415 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1416 if rebootUniVlanConfigEntries, appended =
1417 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1418 waitGroup.Done()
1419 }
1420 } else {
1421 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1422 }
1423 } //switch uniIndication
1424
1425 case <-time.After(expiry):
1426 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1427 log.Fields{"device-id": dh.DeviceID})
1428 return
1429 }
1430 }
1431}
1432
1433func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1434 if dh != nil { //if the object still exists (might have been already deleted in background)
1435 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1436 select {
1437 case dh.chUniVlanConfigOnRebootDone <- value:
1438 default:
1439 }
1440 }
1441}
1442
1443func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
1444 logger.Info(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
1445 techProfInstLoadFailed := false
1446 continueWithFlowConfig := false
1447 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1448 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1449 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1450
1451 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1452 if pDevEntry == nil {
1453 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1454 return continueWithFlowConfig
1455 }
1456 dh.lockDevice.RLock()
1457 if dh.pOnuTP == nil {
1458 //should normally not happen ...
1459 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1460 log.Fields{"device-id": dh.DeviceID})
1461 dh.lockDevice.RUnlock()
1462 return continueWithFlowConfig
1463 }
1464
1465 dh.pOnuTP.LockTpProcMutex()
1466 defer dh.pOnuTP.UnlockTpProcMutex()
1467 defer dh.lockDevice.RUnlock()
1468
1469 pDevEntry.MutexPersOnuConfig.RLock()
1470 persMutexLock := true
1471 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1472 pDevEntry.MutexPersOnuConfig.RUnlock()
1473 logger.Info(ctx, "no uni-configs have been stored - aborting",
1474 log.Fields{"device-id": dh.DeviceID})
1475 return continueWithFlowConfig
1476 }
1477
1478outerLoop:
1479 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1480 uniID := uniData.PersUniID
1481
1482 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1483 logger.Debugw(ctx, "no TPs stored for uniID",
1484 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1485 continue
1486 }
1487 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1488 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1489 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1490 pDevEntry.MutexPersOnuConfig.RUnlock()
1491 persMutexLock = false
1492 for tpID, tpPath := range uniData.PersTpPathMap {
1493 if tpPath != "" {
1494 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1495 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1496 })
1497 // Attempt the initial call before entering the retry loop
1498 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1499 if err != nil {
1500 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1501 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1502 })
1503 techProfInstLoadFailed = true
1504 break outerLoop
1505 }
1506 if iaTechTpInst != nil {
1507 var tpInst tech_profile.TechProfileInstance
1508 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1509 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1510 tpInst = *techTpInst.TpInstance
1511 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1512 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1513 default: // do not support epon or other tech
1514 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1515 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1516 techProfInstLoadFailed = true
1517 break outerLoop
1518 }
1519
1520 continueWithFlowConfig = true
1521 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1522 dctx, cancel := context.WithDeadline(ctx, deadline)
1523
1524 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1525 var wg sync.WaitGroup
1526 wg.Add(1) // for the 1 go routine to finish
1527 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1528 // Wait for either completion or cancellation
1529 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1530 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1531 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1532 techProfInstLoadFailed = true
1533 continueWithFlowConfig = false
1534 break outerLoop
1535 }
1536 } else {
1537 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1538 techProfInstLoadFailed = true
1539 break outerLoop
1540 }
1541 } else {
1542 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1543 "uni-id": uniID, "device-id": dh.DeviceID})
1544 techProfInstLoadFailed = true
1545 break outerLoop
1546 }
1547 }
1548 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1549 persMutexLock = true
1550 }
1551 if persMutexLock {
1552 pDevEntry.MutexPersOnuConfig.RUnlock()
1553 }
1554 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1555 return continueWithFlowConfig
1556}
1557
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001559 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001560
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001561 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001562 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001563 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001565 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001566 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001567
1568 // deadline context to ensure completion of background routines waited for
1569 //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 +05301570 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301572 defer cancel()
1573 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1574 if err != nil {
1575 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1576 return err
1577 }
1578 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001579}
1580
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301581// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001582// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301583//
1584// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1585//
1586// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301587func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001588 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001589 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301591 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001592 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001593 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301594 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001595 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301596 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301597 }
mpagenko01e726e2020-10-23 09:45:29 +00001598
1599 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001600 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001601
mpagenko44bd8362021-11-15 11:40:05 +00001602 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001603 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001604 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
akashreddyke30dfa92025-11-26 10:51:57 +05301605 go func() {
1606 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1607 DeviceId: dh.DeviceID,
1608 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1609 OperStatus: voltha.OperStatus_DISCOVERED,
1610 }); err != nil {
1611 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1612 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1613 return
1614 }
akashreddykb03dde02025-12-02 10:53:18 +05301615 dh.UpdateAndStoreRebootState(ctx, true)
akashreddyke30dfa92025-11-26 10:51:57 +05301616 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1617 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1618 return
1619 }
1620 dh.SetReadyForOmciConfig(false)
1621 }()
1622 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001623 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1624 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1625 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1626 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001627}
1628
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301629// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1630//
1631// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001632func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001634 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001636
1637 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001639 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1641 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001642 }
1643
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001645 var inactiveImageID uint16
1646 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1647 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001648 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1649 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001650 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001652 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001653 if err == nil {
1654 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1655 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001657 }
1658 } else {
1659 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001661 }
mpagenko15ff4a52021-03-02 10:09:20 +00001662 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001663 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001665 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1666 dh.upgradeCanceled = true
1667 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1668 }
mpagenko38662d02021-08-11 09:45:19 +00001669 //no effort spent anymore for the old API to automatically cancel and restart the download
1670 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001671 }
mpagenko15ff4a52021-03-02 10:09:20 +00001672 } else {
1673 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001675 }
1676 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1678 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001679 }
1680 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001681}
1682
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301683// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001684// after the OnuImage has been downloaded to the adapter, called in background
1685func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001687
1688 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001689 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001690 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001692 return
1693 }
1694
1695 var inactiveImageID uint16
1696 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1697 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001698 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001699
mpagenko59862f02021-10-11 08:53:18 +00001700 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001702 // but must be still locked at calling createOnuUpgradeFsm
1703 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1704 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1705 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001706 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1707 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001709 //flush the remove upgradeFsmChan channel
1710 select {
1711 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001712 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001713 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001714 }
mpagenko59862f02021-10-11 08:53:18 +00001715 dh.lockUpgradeFsm.Unlock()
1716 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1717 dh.upgradeCanceled = true
1718 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1719 }
mpagenko38662d02021-08-11 09:45:19 +00001720 select {
1721 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001722 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001723 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1724 return
1725 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001726 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001727 }
mpagenko59862f02021-10-11 08:53:18 +00001728 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001729 }
mpagenko38662d02021-08-11 09:45:19 +00001730
1731 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001732 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001733 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001734 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001735 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001736 if err == nil {
1737 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1738 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1739 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001741 return
1742 }
mpagenko38662d02021-08-11 09:45:19 +00001743 } else {
1744 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001746 }
1747 return
1748 }
1749 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001750 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001751}
1752
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301753// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001754func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1755 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001756 var err error
1757 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1758 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1759 // 2.) activation of the inactive image
1760
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001761 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001762 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001763 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1764 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001765 }
1766 dh.lockUpgradeFsm.RLock()
1767 if dh.pOnuUpradeFsm != nil {
1768 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001769 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001770 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001771 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1772 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001773 }
mpagenko59862f02021-10-11 08:53:18 +00001774 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1775 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1776 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1777 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001778 // use the OnuVendor identification from this device for the internal unique name
1779 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001780 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001781 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001782 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001783 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001784 "device-id": dh.DeviceID, "error": err})
1785 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001786 }
mpagenko183647c2021-06-08 15:25:04 +00001787 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001788 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001789 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001790 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001791 } //else
1792 dh.lockUpgradeFsm.RUnlock()
1793
1794 // 2.) check if requested image-version equals the inactive one and start its activation
1795 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1796 var inactiveImageID uint16
1797 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1798 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001799 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1800 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001801 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001802 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001803 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001804 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001805 if err == nil {
1806 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1807 inactiveImageID, aCommitRequest); err != nil {
1808 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001809 "device-id": dh.DeviceID, "error": err})
1810 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001811 }
1812 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001813 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001814 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001815 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001816 } //else
1817 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001818 "device-id": dh.DeviceID, "error": err})
1819 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001820}
1821
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301822// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001823func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1824 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001825 var err error
1826 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1827 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1828 // 2.) commitment of the active image
1829
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001830 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001831 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001832 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1833 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001834 }
1835 dh.lockUpgradeFsm.RLock()
1836 if dh.pOnuUpradeFsm != nil {
1837 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001839 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1841 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001842 }
mpagenko59862f02021-10-11 08:53:18 +00001843 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1844 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1845 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1846 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001847 // use the OnuVendor identification from this device for the internal unique name
1848 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001849 // 1.) check a started upgrade process and relay the commitment request to it
1850 // the running upgrade may be based either on the imageIdentifier (started from download)
1851 // or on the imageVersion (started from pure activation)
1852 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1853 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001854 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001855 "device-id": dh.DeviceID, "error": err})
1856 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001857 }
mpagenko183647c2021-06-08 15:25:04 +00001858 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001859 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001860 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001861 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001862 } //else
1863 dh.lockUpgradeFsm.RUnlock()
1864
mpagenko183647c2021-06-08 15:25:04 +00001865 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001866 var activeImageID uint16
1867 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1868 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001869 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1870 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001871 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001872 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001873 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001874 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001875 if err == nil {
1876 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1877 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001878 "device-id": dh.DeviceID, "error": err})
1879 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001880 }
1881 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001882 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001883 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001884 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001885 } //else
1886 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001887 "device-id": dh.DeviceID, "error": err})
1888 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001889}
1890
mpagenkoaa3afe92021-05-21 16:20:58 +00001891func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001892 aVersion string) *voltha.ImageState {
1893 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001894 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001895 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001896 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001897 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1898 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1899 if aVersion == dh.pLastUpgradeImageState.Version {
1900 pImageState = dh.pLastUpgradeImageState
1901 } else { //state request for an image version different from last processed image version
1902 pImageState = &voltha.ImageState{
1903 Version: aVersion,
1904 //we cannot state something concerning this version
1905 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1906 Reason: voltha.ImageState_NO_ERROR,
1907 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1908 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001909 }
1910 }
mpagenko38662d02021-08-11 09:45:19 +00001911 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001912}
1913
1914func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1915 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001916 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001917 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001918 dh.lockUpgradeFsm.RLock()
1919 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001920 dh.lockUpgradeFsm.RUnlock()
1921 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001922 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001923 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1924 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1925 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1926 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1927 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1928 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001929 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1930 dh.upgradeCanceled = true
1931 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1932 }
mpagenko45586762021-10-01 08:30:22 +00001933 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001934 } else {
mpagenko45586762021-10-01 08:30:22 +00001935 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001936 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1937 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1938 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1939 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1940 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1941 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001942 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1943 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001944 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1945 //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 +00001946 }
1947}
1948
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001949func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001954 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1956 pDevEntry.MutexOnuImageStatus.Lock()
1957 pDevEntry.POnuImageStatus = onuImageStatus
1958 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001959
1960 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001962 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1963 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1965 pDevEntry.MutexOnuImageStatus.Lock()
1966 pDevEntry.POnuImageStatus = nil
1967 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001968 return images, err
1969}
1970
Himani Chawla6d2ae152020-09-02 13:11:20 +05301971// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001972// #####################################################################################
1973
1974// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301975// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001976
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001978 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1979 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001980}
1981
1982// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001984
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001985 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001986 var err error
1987
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001988 // populate what we know. rest comes later after mib sync
1989 dh.device.Root = false
1990 dh.device.Vendor = "OpenONU"
1991 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001993 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001994
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001995 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001996
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001997 if !dh.IsReconciling() {
1998 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301999 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04002000 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2001 }
Himani Chawlac07fda02020-12-09 16:21:21 +05302002 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002003 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302004 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002005 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002006 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002007
Himani Chawla4d908332020-08-31 12:30:20 +05302008 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002009 dh.ponPortNumber = dh.device.ParentPortNo
2010
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002011 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
2012 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
2013 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002014 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002015 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05302016 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002017
2018 /*
2019 self._pon = PonPort.create(self, self._pon_port_number)
2020 self._pon.add_peer(self.parent_id, self._pon_port_number)
2021 self.logger.debug('adding-pon-port-to-agent',
2022 type=self._pon.get_port().type,
2023 admin_state=self._pon.get_port().admin_state,
2024 oper_status=self._pon.get_port().oper_status,
2025 )
2026 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002027 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302028 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002029 var ponPortNo uint32 = 1
2030 if dh.ponPortNumber != 0 {
2031 ponPortNo = dh.ponPortNumber
2032 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002034 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002035 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002036 PortNo: ponPortNo,
2037 Label: fmt.Sprintf("pon-%d", ponPortNo),
2038 Type: voltha.Port_PON_ONU,
2039 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302040 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002041 PortNo: ponPortNo}}, // Peer port is parent's port number
2042 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002043 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002044 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002045 e.Cancel(err)
2046 return
2047 }
2048 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302049 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002050 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002051 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002052}
2053
2054// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002056
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002057 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002058 var err error
2059 /*
2060 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2061 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2062 return nil
2063 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002065 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002066 e.Cancel(err)
2067 return
2068 }
2069
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002070 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002072 // reconcilement will be continued after mib download is done
2073 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002074
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002075 /*
2076 ############################################################################
2077 # Setup Alarm handler
2078 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2079 device.serial_number)
2080 ############################################################################
2081 # Setup PM configuration for this device
2082 # Pass in ONU specific options
2083 kwargs = {
2084 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2085 'heartbeat': self.heartbeat,
2086 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2087 }
2088 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2089 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2090 self.logical_device_id, device.serial_number,
2091 grouped=True, freq_override=False, **kwargs)
2092 pm_config = self._pm_metrics.make_proto()
2093 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2094 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2095 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2096
2097 # Note, ONU ID and UNI intf set in add_uni_port method
2098 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2099 ani_ports=[self._pon])
2100
2101 # Code to Run OMCI Test Action
2102 kwargs_omci_test_action = {
2103 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2104 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2105 }
2106 serial_number = device.serial_number
2107 self._test_request = OmciTestRequest(self.core_proxy,
2108 self.omci_agent, self.device_id,
2109 AniG, serial_number,
2110 self.logical_device_id,
2111 exclusive=False,
2112 **kwargs_omci_test_action)
2113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002114 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002115 else:
2116 self.logger.info('onu-already-activated')
2117 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002118
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002119 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002120}
2121
2122// doStateConnected get the device info and update to voltha core
2123// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302124//
2125// voltha-openolt-adapter/adaptercore/device_handler.go
2126// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002128
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002129 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302130 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002131 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002132 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002133}
2134
2135// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002137
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002138 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302139 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002141 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002142
2143 /*
2144 // Synchronous call to update device state - this method is run in its own go routine
2145 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2146 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002147 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 +00002148 return err
2149 }
2150 return nil
2151 */
2152}
2153
2154// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002156
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002157 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002158 var err error
2159
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002160 device := dh.device
2161 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002162 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002164 e.Cancel(err)
2165 return
2166 }
2167
2168 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002170 /*
2171 // Update the all ports state on that device to disable
2172 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002173 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002174 return er
2175 }
2176
2177 //Update the device oper state and connection status
2178 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2179 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2180 dh.device = cloned
2181
2182 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002183 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002184 return er
2185 }
2186
2187 //get the child device for the parent device
2188 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2189 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002190 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002191 return err
2192 }
2193 for _, onuDevice := range onuDevices.Items {
2194
2195 // Update onu state as down in onu adapter
2196 onuInd := oop.OnuIndication{}
2197 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002198 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002199 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2200 if er != nil {
2201 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002202 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002203 //Do not return here and continue to process other ONUs
2204 }
2205 }
2206 // * Discovered ONUs entries need to be cleared , since after OLT
2207 // is up, it starts sending discovery indications again* /
2208 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002209 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002210 return nil
2211 */
Himani Chawla4d908332020-08-31 12:30:20 +05302212 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002213 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002214 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002215}
2216
Himani Chawla6d2ae152020-09-02 13:11:20 +05302217// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002218// #################################################################################
2219
2220// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302221// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002222
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302223// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002225 dh.lockDevice.RLock()
2226 pOnuDeviceEntry := dh.pOnuOmciDevice
2227 if aWait && pOnuDeviceEntry == nil {
2228 //keep the read sema short to allow for subsequent write
2229 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002230 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002231 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2232 // so it might be needed to wait here for that event with some timeout
2233 select {
2234 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002235 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002236 return nil
2237 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002239 // if written now, we can return the written value without sema
2240 return dh.pOnuOmciDevice
2241 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002242 }
mpagenko3af1f032020-06-10 08:53:41 +00002243 dh.lockDevice.RUnlock()
2244 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002245}
2246
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302247// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2249 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002250 dh.lockDevice.Lock()
2251 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002252 dh.pOnuOmciDevice = apDeviceEntry
2253 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002254 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302255 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002256 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002257}
2258
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302259// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302260//
2261//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302262func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002264
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002265 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002266 if deviceEntry == nil {
2267 /* costum_me_map in python code seems always to be None,
2268 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2269 /* also no 'clock' argument - usage open ...*/
2270 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2272 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2273 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2274 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2275 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002276 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002278 // fire deviceEntry ready event to spread to possibly waiting processing
2279 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002281 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002282 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002283 }
2284 // might be updated with some error handling !!!
2285 return nil
2286}
2287
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002289 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002290 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2291
2292 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002293
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002295 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2297 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002298 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302299
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002303
khenaidoo42dcdfd2021-10-19 17:34:12 -04002304 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002306 OperStatus: voltha.OperStatus_ACTIVATING,
2307 ConnStatus: voltha.ConnectStatus_REACHABLE,
2308 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002309 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302311 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2312 }
2313 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2314 if dh.GetDeviceTechProfOnReboot() {
2315 pDevEntry.MutexPersOnuConfig.Lock()
2316 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2317 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
akashreddykb03dde02025-12-02 10:53:18 +05302318 pDevEntry.SOnuPersistentData.PersUniUnlockDone = false
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302319 pDevEntry.MutexPersOnuConfig.Unlock()
2320 }
2321 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2322 if err := dh.StorePersistentData(ctx); err != nil {
2323 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2324 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002325 }
2326 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302327 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002329
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 pDevEntry.MutexPersOnuConfig.RLock()
2331 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2332 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 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 +00002334 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002335 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302336
2337 //VOL-4965: Recover previously Activating ONU during reconciliation.
2338 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2339 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2340 log.Fields{"device-id": dh.DeviceID})
2341 pDevEntry.MutexPersOnuConfig.Lock()
2342 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2343 pDevEntry.MutexPersOnuConfig.Unlock()
2344 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002345 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002346 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002347 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002348 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002349 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2350 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2351 // 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 +00002352 // 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 +00002353 // so let's just try to keep it simple ...
2354 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002356 if err != nil || device == nil {
2357 //TODO: needs to handle error scenarios
2358 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2359 return errors.New("Voltha Device not found")
2360 }
2361 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002362
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002364 return err
mpagenko3af1f032020-06-10 08:53:41 +00002365 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002366 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302367 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2368 /* this might be a good time for Omci Verify message? */
2369 verifyExec := make(chan bool)
2370 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2371 dh.device.Id, pDevEntry.PDevOmciCC, false,
2372 true, true) //exclusive and allowFailure (anyway not yet checked)
2373 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002374
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302375 /* give the handler some time here to wait for the OMCi verification result
2376 after Timeout start and try MibUpload FSM anyway
2377 (to prevent stopping on just not supported OMCI verification from ONU) */
2378 select {
2379 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2380 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2381 case testresult := <-verifyExec:
2382 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2383 case <-dh.deviceDeleteCommChan:
2384 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2385 return nil
2386 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002387 }
2388
2389 /* In py code it looks earlier (on activate ..)
2390 # Code to Run OMCI Test Action
2391 kwargs_omci_test_action = {
2392 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2393 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2394 }
2395 serial_number = device.serial_number
2396 self._test_request = OmciTestRequest(self.core_proxy,
2397 self.omci_agent, self.device_id,
2398 AniG, serial_number,
2399 self.logical_device_id,
2400 exclusive=False,
2401 **kwargs_omci_test_action)
2402 ...
2403 # Start test requests after a brief pause
2404 if not self._test_request_started:
2405 self._test_request_started = True
2406 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2407 reactor.callLater(tststart, self._test_request.start_collector)
2408
2409 */
2410 /* which is then: in omci_test_request.py : */
2411 /*
2412 def start_collector(self, callback=None):
2413 """
2414 Start the collection loop for an adapter if the frequency > 0
2415
2416 :param callback: (callable) Function to call to collect PM data
2417 """
2418 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2419 if callback is None:
2420 callback = self.perform_test_omci
2421
2422 if self.lc is None:
2423 self.lc = LoopingCall(callback)
2424
2425 if self.default_freq > 0:
2426 self.lc.start(interval=self.default_freq / 10)
2427
2428 def perform_test_omci(self):
2429 """
2430 Perform the initial test request
2431 """
2432 ani_g_entities = self._device.configuration.ani_g_entities
2433 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2434 is not None else None
2435 self._entity_id = ani_g_entities_ids[0]
2436 self.logger.info('perform-test', entity_class=self._entity_class,
2437 entity_id=self._entity_id)
2438 try:
2439 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2440 result = yield self._device.omci_cc.send(frame)
2441 if not result.fields['omci_message'].fields['success_code']:
2442 self.logger.info('Self-Test Submitted Successfully',
2443 code=result.fields[
2444 'omci_message'].fields['success_code'])
2445 else:
2446 raise TestFailure('Test Failure: {}'.format(
2447 result.fields['omci_message'].fields['success_code']))
2448 except TimeoutError as e:
2449 self.deferred.errback(failure.Failure(e))
2450
2451 except Exception as e:
2452 self.logger.exception('perform-test-Error', e=e,
2453 class_id=self._entity_class,
2454 entity_id=self._entity_id)
2455 self.deferred.errback(failure.Failure(e))
2456
2457 */
2458
2459 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002461
mpagenko1cc3cb42020-07-27 15:24:38 +00002462 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2463 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2464 * 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 +05302465 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002466 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302467
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302469 // Breaking this part of code due to sca complexity
2470 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2471 return err
2472}
2473
2474func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002476 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477 if pMibUlFsm.Is(mib.UlStDisabled) {
2478 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2479 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2480 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302481 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002482 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302483 //Determine ONU status and start/re-start MIB Synchronization tasks
2484 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 if pDevEntry.IsNewOnu() {
2486 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2487 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2488 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002489 }
Himani Chawla4d908332020-08-31 12:30:20 +05302490 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002491 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2492 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2493 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302494 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002495 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002496 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002497 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002498 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499 "device-id": dh.DeviceID})
2500 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002501 }
2502 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2504 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002505 }
2506 return nil
2507}
2508
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002509func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002510 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002511 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302513 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002514
mpagenko900ee4b2020-10-12 11:56:34 +00002515 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2516 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2517 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002518 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002521 // abort: system behavior is just unstable ...
2522 return err
2523 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002524 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302525 if !dh.GetDeviceTechProfOnReboot() {
2526 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2527 }
mpagenko900ee4b2020-10-12 11:56:34 +00002528
2529 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002530 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002532 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2534 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002535 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002537
2538 //TODO!!! remove existing traffic profiles
2539 /* from py code, if TP's exist, remove them - not yet implemented
2540 self._tp = dict()
2541 # Let TP download happen again
2542 for uni_id in self._tp_service_specific_task:
2543 self._tp_service_specific_task[uni_id].clear()
2544 for uni_id in self._tech_profile_download_done:
2545 self._tech_profile_download_done[uni_id].clear()
2546 */
2547
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002549
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002550 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002551
mpagenkoe4782082021-11-25 12:04:26 +00002552 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002553 // abort: system behavior is just unstable ...
2554 return err
2555 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002556 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002558 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002560 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2561 OperStatus: voltha.OperStatus_DISCOVERED,
2562 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002563 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002564 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002566 // abort: system behavior is just unstable ...
2567 return err
2568 }
akashreddykb03dde02025-12-02 10:53:18 +05302569 if dh.GetDeviceTechProfOnReboot() {
2570 logger.Debugw(ctx, "Storing OnuPersData during device-down-indication", log.Fields{"device": dh.DeviceID, "onu-pers-data": dh.pOnuOmciDevice.SOnuPersistentData})
2571 if err := dh.StorePersistentData(ctx); err != nil {
2572 logger.Warnw(ctx, "store persistent data error - Failed to store DownIndication",
2573 log.Fields{"device-id": dh.DeviceID, "err": err})
2574 }
2575 }
mpagenko3af1f032020-06-10 08:53:41 +00002576 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002578 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002579 return nil
2580}
2581
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002582func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002583 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2584 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2585 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2586 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002587 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002588
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302590 //VOL-5260: During race conditions when adoptDevice has not yet completed
2591 // and deleteDevice is issued , returning error will further prevent clean up
2592 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002593 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302594 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2595 logger.Error(ctx, errMsg)
2596 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002597 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002598 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002599 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 pDevEntry.MutexOnuImageStatus.RLock()
2602 if pDevEntry.POnuImageStatus != nil {
2603 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002604 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002606
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002607 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002608 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002609 }
2610 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002612 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002613 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002614 }
mpagenko101ac942021-11-16 15:01:29 +00002615 //stop any deviceHandler reconcile processing (if running)
2616 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002617 //port lock/unlock FSM's may be active
2618 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002619 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002620 }
2621 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002623 }
2624 //techProfile related PonAniConfigFsm FSM may be active
2625 if dh.pOnuTP != nil {
2626 // should always be the case here
2627 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002628 if dh.pOnuTP.PAniConfigFsm != nil {
2629 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2630 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002631 }
mpagenko900ee4b2020-10-12 11:56:34 +00002632 }
2633 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002634 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002635 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002637 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002638 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002639 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002640 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002641 } else {
2642 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002643 }
2644 }
2645 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302646
2647 dh.mutexCollectorFlag.Lock()
2648 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2649 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002650 // Stop collector routine
2651 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302652 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002653 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302654 dh.mutexCollectorFlag.Unlock()
2655
2656 dh.mutextAlarmManagerFlag.Lock()
2657 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2658 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302659 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302660 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302661 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302662 dh.mutextAlarmManagerFlag.Unlock()
2663
2664 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2665 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2666 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302668 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002669 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302670 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302671
Girish Gowdrae95687a2021-09-08 16:30:58 -07002672 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2673
mpagenko80622a52021-02-09 16:53:23 +00002674 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002676 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002677 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002679 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002680 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002681 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2682 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2683 // (even though it may also run into direct cancellation, a bit hard to verify here)
2684 // so don't set 'dh.upgradeCanceled = true' here!
2685 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2686 }
mpagenko38662d02021-08-11 09:45:19 +00002687 }
mpagenko80622a52021-02-09 16:53:23 +00002688
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002690 return nil
2691}
2692
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302693//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2695 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 +05302696
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002697 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002699 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002700 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002701 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002702 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002704
mpagenkoa40e99a2020-11-17 13:50:39 +00002705 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2706 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2707 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2708 * disable/enable toggling here to allow traffic
2709 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2710 * like the py comment says:
2711 * # start by locking all the unis till mib sync and initial mib is downloaded
2712 * # this way we can capture the port down/up events when we are ready
2713 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302714
mpagenkoa40e99a2020-11-17 13:50:39 +00002715 // Init Uni Ports to Admin locked state
2716 // *** should generate UniLockStateDone event *****
2717 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002719 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002722 }
2723}
2724
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302725//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002726func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2727 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302728 /* Mib download procedure -
2729 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2730 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002731 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002732 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002734 return
2735 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302737 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 if pMibDlFsm.Is(mib.DlStDisabled) {
2739 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2740 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 +05302741 // maybe try a FSM reset and then again ... - TODO!!!
2742 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002743 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302744 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2746 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302747 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002748 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302749 //Begin MIB data download (running autonomously)
2750 }
2751 }
2752 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002753 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302755 // maybe try a FSM reset and then again ... - TODO!!!
2756 }
2757 /***** Mib download started */
2758 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302760 }
2761}
2762
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302763//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302765 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002766 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2767 if pDevEntry == nil {
2768 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2769 return
2770 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002771 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002772 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002774 // update device info in core
2775 pDevEntry.MutexPersOnuConfig.RLock()
2776 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2777 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2778 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2779 pDevEntry.MutexPersOnuConfig.RUnlock()
2780 dh.logicalDeviceID = dh.DeviceID
2781 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2782 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2783 }
2784 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002785 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2786 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2787 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2788 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002789 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002791 ConnStatus: voltha.ConnectStatus_REACHABLE,
2792 OperStatus: voltha.OperStatus_ACTIVE,
2793 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302794 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302796 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302798 }
2799 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302800 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302802 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002803 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002804
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002805 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002806 var waitForOmciProcessor sync.WaitGroup
2807 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002808 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002809 go dh.StartCollector(ctx, &waitForOmciProcessor)
2810 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002811 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002812 if !dh.GetAlarmManagerIsRunning(ctx) {
2813 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002814 }
2815
Girish Gowdrae95687a2021-09-08 16:30:58 -07002816 // Start flow handler routines per UNI
2817 for _, uniPort := range dh.uniEntityMap {
2818 // only if this port was enabled for use by the operator at startup
2819 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2820 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2821 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2822 }
2823 }
2824 }
2825
Girish Gowdrae0140f02021-02-02 16:55:09 -08002826 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002827 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002828 // There is no way we should be landing here, but if we do then
2829 // there is nothing much we can do about this other than log error
2830 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2831 }
2832
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002835 pDevEntry.MutexPersOnuConfig.RLock()
2836 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2837 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302838 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002840 dh.mutexForDisableDeviceRequested.Lock()
2841 dh.disableDeviceRequested = true
2842 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002843 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002844 // reconcilement will be continued after ani config is done
2845 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002847 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002848 dh.mutexForDisableDeviceRequested.RLock()
2849 if !dh.disableDeviceRequested {
2850 if dh.pUnlockStateFsm == nil {
2851 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2852 } else { //UnlockStateFSM already init
2853 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2854 dh.runUniLockFsm(ctx, false)
2855 }
2856 dh.mutexForDisableDeviceRequested.RUnlock()
2857 } else {
2858 dh.mutexForDisableDeviceRequested.RUnlock()
2859 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002860 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302861 }
2862}
2863
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302864//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2866 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302869 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2870 if dh.GetDeviceTechProfOnReboot() {
2871 if dh.CheckForDeviceTechProf(ctx) {
2872 go dh.DeviceFlowConfigOnReboot(ctx)
2873 }
2874 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002875 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002876 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2878 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002879 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002880 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002881 return
2882 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 pDevEntry.MutexPersOnuConfig.Lock()
2884 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2885 pDevEntry.MutexPersOnuConfig.Unlock()
2886 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002888 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002889 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302890 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302891 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 +00002892 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002893 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302894
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002895 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302896
Himani Chawla26e555c2020-08-31 12:30:20 +05302897 }
2898}
2899
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302900//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002901func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002902 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002904
mpagenko44bd8362021-11-15 11:40:05 +00002905 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002906 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002907 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002908 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002909 OperStatus: voltha.OperStatus_UNKNOWN,
2910 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002911 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002913 }
2914
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002916 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002917 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002918
2919 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002921
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002923 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002925 return
2926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 pDevEntry.MutexPersOnuConfig.Lock()
2928 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2929 pDevEntry.MutexPersOnuConfig.Unlock()
2930 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002933 }
mpagenko900ee4b2020-10-12 11:56:34 +00002934}
2935
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302936//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002938 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002940 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002941 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002942 ConnStatus: voltha.ConnectStatus_REACHABLE,
2943 OperStatus: voltha.OperStatus_ACTIVE,
2944 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002945 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002947 }
2948
dbainbri4d3a0dc2020-12-02 00:33:42 +00002949 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002951 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002952 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002953
2954 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002956
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002958 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002960 return
2961 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002962 pDevEntry.MutexPersOnuConfig.Lock()
2963 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2964 pDevEntry.MutexPersOnuConfig.Unlock()
2965 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002966 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002967 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002968 }
mpagenko900ee4b2020-10-12 11:56:34 +00002969}
2970
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302971//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002972func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2973 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2974 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002975 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002976 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002977 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002978 OperStatus: voltha.OperStatus_FAILED,
2979 }); err != nil {
2980 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2981 }
2982}
2983
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2985 if devEvent == cmn.OmciAniConfigDone {
2986 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002987 // attention: the device reason update is done based on ONU-UNI-Port related activity
2988 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002990 // 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 +00002991 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302992 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002993 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002994 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2995 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2996 dh.mutexReconcilingFirstPassFlag.Lock()
2997 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302998 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002999 dh.reconcilingFirstPass = false
3000 go dh.ReconcileDeviceFlowConfig(ctx)
3001 }
3002 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00003003 }
3004 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003006 // attention: the device reason update is done based on ONU-UNI-Port related activity
3007 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00003009 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
3010 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00003011 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003012 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303013}
3014
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003016 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05303018 // attention: the device reason update is done based on ONU-UNI-Port related activity
3019 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05303020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
3022 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00003023 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00003024 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00003025 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00003026 }
3027 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00003029 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00003030 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003031 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303032 }
mpagenkof1fc3862021-02-16 10:09:52 +00003033
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003035 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003037 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003038 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003039 }
3040 } else {
3041 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003043 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303044}
3045
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303046// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303048 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003049 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003050 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003051 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003052 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003053 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003054 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003055 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003056 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003058 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003059 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003060 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003062 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003063 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003064 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003066 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003067 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003068 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003069 case cmn.UniEnableStateFailed:
3070 {
3071 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3072 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003073 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003074 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003076 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003078 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003079 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003080 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003082 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003083 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003084 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003085 default:
3086 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003087 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003088 }
3089 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003090}
3091
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003092func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003093 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003094 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303095 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003096 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003097 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003098 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303099 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003100 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003101 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003102 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 +00003103 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003104 //store UniPort with the System-PortNumber key
3105 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003107 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003108 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003109 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003110 } //error logging already within UniPort method
3111 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303112 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003113 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003114 }
3115 }
3116}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003117
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3119 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003120 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003122 return
3123 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003124 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003126 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3127 for _, mgmtEntityID := range pptpInstKeys {
3128 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003130 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3131 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003132 }
3133 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003135 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003137 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3138 for _, mgmtEntityID := range veipInstKeys {
3139 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003140 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003141 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3142 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003143 }
3144 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003145 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003146 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003148 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3149 for _, mgmtEntityID := range potsInstKeys {
3150 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003152 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3153 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003154 }
3155 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003156 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003157 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003158 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003159 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003160 return
3161 }
3162
mpagenko2c3f6c52021-11-23 11:22:10 +00003163 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3164 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3165 // 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 -07003166 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3167 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3168 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003169 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3170 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303171 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003172 for i := 0; i < int(uniCnt); i++ {
3173 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003174 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003175 }
3176}
3177
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3179func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003180 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303181 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003182 // with following remark:
3183 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3184 // # load on the core
3185
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003186 // 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 +00003187
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003188 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003189 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3191 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303192 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003193 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003194 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003196 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003198 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003199 PortNo: port.PortNo,
3200 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003201 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003202 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 -04003203 }
3204 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003205 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303206 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003207 }
mpagenko3af1f032020-06-10 08:53:41 +00003208 }
3209 }
3210}
3211
3212// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003213func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3214 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003215 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3216 for uniNo, uniPort := range dh.uniEntityMap {
3217 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003218
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3220 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303221 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003223 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003224 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003225 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003226 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003227 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003228 PortNo: port.PortNo,
3229 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003230 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003231 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 -04003232 }
3233 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003234 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303235 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003236 }
3237
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003238 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003239 }
3240}
3241
3242// ONU_Active/Inactive announcement on system KAFKA bus
3243// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303244func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003245 var de voltha.DeviceEvent
3246 eventContext := make(map[string]string)
3247 //Populating event context
3248 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003249 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003250 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003251 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003252 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003253 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 +00003254 }
3255 oltSerialNumber := parentDevice.SerialNumber
3256
3257 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3258 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3259 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303260 eventContext["olt-serial-number"] = oltSerialNumber
3261 eventContext["device-id"] = aDeviceID
3262 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003263 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003264 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3265 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003266 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3267 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3269 deviceEntry.MutexPersOnuConfig.RUnlock()
3270 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003272 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3273 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3274 } else {
3275 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3276 log.Fields{"device-id": aDeviceID})
3277 return
3278 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003279
3280 /* Populating device event body */
3281 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303282 de.ResourceId = aDeviceID
3283 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003284 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3285 de.Description = fmt.Sprintf("%s Event - %s - %s",
3286 cEventObjectType, cOnuActivatedEvent, "Raised")
3287 } else {
3288 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3289 de.Description = fmt.Sprintf("%s Event - %s - %s",
3290 cEventObjectType, cOnuActivatedEvent, "Cleared")
3291 }
3292 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303293 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003294 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303295 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003296 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303297 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303298 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003299}
3300
Himani Chawla4d908332020-08-31 12:30:20 +05303301// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003302func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303303 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003304 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303305 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003306 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003307 sFsmName = "LockStateFSM"
3308 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003310 sFsmName = "UnLockStateFSM"
3311 }
mpagenko3af1f032020-06-10 08:53:41 +00003312
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003313 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00003314 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003315 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003316 return
3317 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003318 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003319 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303320 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003321 dh.pLockStateFsm = pLSFsm
3322 } else {
3323 dh.pUnlockStateFsm = pLSFsm
3324 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003325 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003326 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003327 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003328 }
3329}
3330
3331// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003332func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003333 /* Uni Port lock/unlock procedure -
3334 ***** should run via 'adminDone' state and generate the argument requested event *****
3335 */
3336 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303337 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003339 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3340 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3342 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003343 }
3344 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003345 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003346 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3347 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003348 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3349 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003350 }
3351 }
3352 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003353 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3354 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003355 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003356 // maybe try a FSM reset and then again ... - TODO!!!
3357 } else {
3358 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003359 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003360 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003361 }
3362 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003363 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003364 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003365 // maybe try a FSM reset and then again ... - TODO!!!
3366 }
3367 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003369 // maybe try a FSM reset and then again ... - TODO!!!
3370 }
3371}
3372
mpagenko80622a52021-02-09 16:53:23 +00003373// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003374// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303375//
3376//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003377func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303378 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003379 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003381 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003382 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303383 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003384 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003386 sFsmName, chUpgradeFsm)
3387 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003389 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3391 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003392 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003393 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303394 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003395 }
mpagenko59862f02021-10-11 08:53:18 +00003396 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003397 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3398 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003399 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3400 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003401 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003403 } else {
3404 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003405 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003406 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303407 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003408 }
3409 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003411 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303412 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003413 }
3414 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003415 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303416 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003417 }
3418 return nil
3419}
3420
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3422func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003423 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003425 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003426 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3427 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003428 dh.pLastUpgradeImageState = apImageState
3429 dh.lockUpgradeFsm.Unlock()
3430 //signal upgradeFsm removed using non-blocking channel send
3431 select {
3432 case dh.upgradeFsmChan <- struct{}{}:
3433 default:
3434 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003436 }
mpagenko80622a52021-02-09 16:53:23 +00003437}
3438
mpagenko15ff4a52021-03-02 10:09:20 +00003439// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3440func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003441 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003442 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003443 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003444 return
3445 }
3446
3447 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003448 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003449 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003450 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3451 dh.lockUpgradeFsm.RUnlock()
3452 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3453 return
3454 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003456 if pUpgradeStatemachine != nil {
3457 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3458 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 UpgradeState := pUpgradeStatemachine.Current()
3460 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3461 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3462 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003463 // 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 +00003464 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003465 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3466 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003467 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003468 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003470 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3471 dh.upgradeCanceled = true
3472 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3473 }
mpagenko15ff4a52021-03-02 10:09:20 +00003474 return
3475 }
mpagenko59862f02021-10-11 08:53:18 +00003476 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003477 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3478 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003479 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003481 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3482 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003483 return
3484 }
3485 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003487 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3489 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003490 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3491 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003492 return
3493 }
3494 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003495 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003496 }
3497 } else {
3498 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 +00003499 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003500 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3501 dh.upgradeCanceled = true
3502 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3503 }
mpagenko1f8e8822021-06-25 14:10:21 +00003504 }
mpagenko15ff4a52021-03-02 10:09:20 +00003505 return
3506 }
mpagenko59862f02021-10-11 08:53:18 +00003507 dh.lockUpgradeFsm.RUnlock()
3508 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3509 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003510 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3511 dh.upgradeCanceled = true
3512 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3513 }
mpagenko59862f02021-10-11 08:53:18 +00003514 return
3515 }
3516 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3517 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3518 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3519 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3520 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3521 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3522 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003523 }
mpagenko15ff4a52021-03-02 10:09:20 +00003524 }
3525 }
3526 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003528 }
mpagenko59862f02021-10-11 08:53:18 +00003529 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003530}
3531
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303532// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003534
3535 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003537 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003538 kvbackend := &db.Backend{
3539 Client: dh.pOpenOnuAc.kvClient,
3540 StoreType: dh.pOpenOnuAc.KVStoreType,
3541 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003542 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003543 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3544 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003545
mpagenkoaf801632020-07-03 10:00:42 +00003546 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003547}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303548
3549//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003550func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303551 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003552
mpagenkodff5dda2020-08-28 11:52:01 +00003553 for _, field := range flow.GetOfbFields(apFlowItem) {
3554 switch field.Type {
3555 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3556 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003557 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003558 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3559 }
mpagenko01e726e2020-10-23 09:45:29 +00003560 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003561 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3562 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303563 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003564 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303565 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3566 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003567 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3568 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003569 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303571 return
mpagenkodff5dda2020-08-28 11:52:01 +00003572 }
3573 }
mpagenko01e726e2020-10-23 09:45:29 +00003574 */
mpagenkodff5dda2020-08-28 11:52:01 +00003575 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3576 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303577 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003578 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303579 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3580 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303581 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003582 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303584 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003585 }
3586 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3587 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303588 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003589 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303590 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003591 }
3592 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3593 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003595 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3596 }
3597 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3598 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003599 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003600 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3601 }
3602 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3603 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003604 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003605 "IPv4-DST": field.GetIpv4Dst()})
3606 }
3607 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3608 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003610 "IPv4-SRC": field.GetIpv4Src()})
3611 }
3612 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3613 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003615 "Metadata": field.GetTableMetadata()})
3616 }
3617 /*
3618 default:
3619 {
3620 //all other entires ignored
3621 }
3622 */
3623 }
3624 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303625}
mpagenkodff5dda2020-08-28 11:52:01 +00003626
khenaidoo7d3c5582021-08-11 18:09:44 -04003627func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003628 for _, action := range flow.GetActions(apFlowItem) {
3629 switch action.Type {
3630 /* not used:
3631 case of.OfpActionType_OFPAT_OUTPUT:
3632 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003633 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003634 "Output": action.GetOutput()})
3635 }
3636 */
3637 case of.OfpActionType_OFPAT_PUSH_VLAN:
3638 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003639 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003640 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3641 }
3642 case of.OfpActionType_OFPAT_SET_FIELD:
3643 {
3644 pActionSetField := action.GetSetField()
3645 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003646 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003647 "OxcmClass": pActionSetField.Field.OxmClass})
3648 }
3649 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303650 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003651 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303652 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003653 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303654 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303656 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003657 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003659 "Type": pActionSetField.Field.GetOfbField().Type})
3660 }
3661 }
3662 /*
3663 default:
3664 {
3665 //all other entires ignored
3666 }
3667 */
3668 }
3669 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303670}
3671
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303672// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003673func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003674 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303675 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3676 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303677 var loSetPcp uint8
3678 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303679 var loIPProto uint32
3680 /* the TechProfileId is part of the flow Metadata - compare also comment within
3681 * OLT-Adapter:openolt_flowmgr.go
3682 * Metadata 8 bytes:
3683 * Most Significant 2 Bytes = Inner VLAN
3684 * Next 2 Bytes = Tech Profile ID(TPID)
3685 * Least Significant 4 Bytes = Port ID
3686 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3687 * subscriber related flows.
3688 */
3689
dbainbri4d3a0dc2020-12-02 00:33:42 +00003690 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303691 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003692 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003693 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003694 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303695 }
mpagenko551a4d42020-12-08 18:09:20 +00003696 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003697 loCookie := apFlowItem.GetCookie()
3698 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303699 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303701 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303702
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303703 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003704 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303705 if loIPProto == 2 {
3706 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3707 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003708 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303710 return nil
3711 }
mpagenko01e726e2020-10-23 09:45:29 +00003712 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003713 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003714
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303715 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3716 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003717 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003719 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3720 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3721 //TODO!!: Use DeviceId within the error response to rwCore
3722 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003723 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003724 }
3725 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003726 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003727 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303728 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3729 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3730 loSetVlan = loMatchVlan
3731 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 +00003732 } else {
3733 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3734 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3735 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303736 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003737 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003739 }
mpagenko9a304ea2020-12-16 15:54:01 +00003740
khenaidoo42dcdfd2021-10-19 17:34:12 -04003741 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003742 if apFlowMetaData != nil {
3743 meter = apFlowMetaData.Meters[0]
3744 }
mpagenkobc4170a2021-08-17 16:42:10 +00003745 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3746 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3747 // when different rules are requested concurrently for the same uni
3748 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3749 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3750 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003751 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3752 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003753 //SetUniFlowParams() may block on some rule that is suspended-to-add
3754 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003755 // Also the error is returned to caller via response channel
3756 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303757 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003758 dh.lockVlanConfig.RUnlock()
3759 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003760 return
mpagenkodff5dda2020-08-28 11:52:01 +00003761 }
mpagenkobc4170a2021-08-17 16:42:10 +00003762 dh.lockVlanConfig.RUnlock()
3763 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003764 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303765 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003766 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003767 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003768 if err != nil {
3769 *respChan <- err
3770 }
mpagenko01e726e2020-10-23 09:45:29 +00003771}
3772
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303773// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003774func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003775 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3776 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3777 //no extra check is done on the rule parameters
3778 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3779 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3780 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3781 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003782 // - 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 +00003783 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003784 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003785
3786 /* TT related temporary workaround - should not be needed anymore
3787 for _, field := range flow.GetOfbFields(apFlowItem) {
3788 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3789 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003790 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003791 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3792 if loIPProto == 2 {
3793 // 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 +00003794 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003795 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003796 return nil
3797 }
3798 }
3799 } //for all OfbFields
3800 */
3801
mpagenko9a304ea2020-12-16 15:54:01 +00003802 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003803 dh.lockVlanConfig.RLock()
3804 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003805 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3806 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003807 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3808 return
mpagenko01e726e2020-10-23 09:45:29 +00003809 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003810 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003812 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003813 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003814 // Push response on the response channel
3815 if respChan != nil {
3816 // 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
3817 select {
3818 case *respChan <- nil:
3819 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3820 default:
3821 }
3822 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003823 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003824}
3825
Himani Chawla26e555c2020-08-31 12:30:20 +05303826// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003827// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003828// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303830 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 +05303831 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003832
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003833 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003834 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003835 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3836 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003837 }
3838
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303839 if dh.pDeviceStateFsm.Current() == devStDown {
3840 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3841 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3842 }
3843
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003844 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3845 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303846 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003847 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003848 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3849 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3851 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003852 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3854 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003855 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3856 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003858 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303859 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003860 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3862 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003863 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003864 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003865 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3866 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003867 }
3868 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003869 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870 "device-id": dh.DeviceID})
3871 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003872 }
3873 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003874 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003875 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3876 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003877 }
3878 return nil
3879}
3880
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303881// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003882// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003883func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003884 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003886 for _, uniPort := range dh.uniEntityMap {
3887 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003888 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003889 pCurrentUniPort = uniPort
3890 break //found - end search loop
3891 }
3892 }
3893 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003894 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003896 return
3897 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003898 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003899}
3900
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303901// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003903 //TODO!! verify and start pending flow configuration
3904 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3905 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303906 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003907 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003909 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003910 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003911 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003912 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003913 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003914 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3916 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003917 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003918 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003919 } else {
3920 /***** UniVlanConfigFsm continued */
3921 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003922 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3923 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003924 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3926 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003927 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003929 } else {
3930 /***** UniVlanConfigFsm continued */
3931 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3933 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003934 }
mpagenkodff5dda2020-08-28 11:52:01 +00003935 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003936 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003937 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3938 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003939 }
3940 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003941 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 +00003942 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3943 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003944 }
3945 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003946 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003947 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003948 }
mpagenkof1fc3862021-02-16 10:09:52 +00003949 } else {
3950 dh.lockVlanConfig.RUnlock()
3951 }
mpagenkodff5dda2020-08-28 11:52:01 +00003952}
3953
Akash Soni3de0e062024-12-11 16:37:26 +05303954// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3955func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3956 dh.lockVlanConfig.Lock()
3957 defer dh.lockVlanConfig.Unlock()
3958
3959 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3960 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3961 if pVlanFilterStatemachine != nil {
3962 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3963 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3964 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3965 })
3966 } else {
3967 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3968 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3969 })
3970 }
3971 } else {
3972 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3973 "device-id": dh.DeviceID, "UniPort": uniID,
3974 })
3975 }
3976 } else {
3977 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3978 "device-id": dh.DeviceID, "UniPort": uniID,
3979 })
3980 }
3981}
3982
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303983// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003984// 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 +00003985func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003986 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003987 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003988 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003989 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003990 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003991 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003992}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003993
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303994// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003996 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3997 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3998 // obviously then parallel processing on the cancel must be avoided
3999 // deadline context to ensure completion of background routines waited for
4000 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
4001 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
4002 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05304003 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00004004
Akash Soni840f8d62024-12-11 19:37:06 +05304005 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
4006 if err != nil {
4007 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
4008 return err
4009 }
4010 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00004011}
4012
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304013// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
4014// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004015func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
4016 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004017
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004018 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304019 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004020 return nil
4021 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004022 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004025 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004026 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
4027 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004028 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004030
mpagenkof1fc3862021-02-16 10:09:52 +00004031 if aWriteToKvStore {
4032 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4033 }
4034 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004035}
4036
dbainbri4d3a0dc2020-12-02 00:33:42 +00004037func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004038 defer cancel() //ensure termination of context (may be pro forma)
4039 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004040 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004041 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004042}
4043
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304044// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4045//
4046// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004047func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4048 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4049 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4050 dh.mutexDeviceReason.Lock()
4051 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004052 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004053 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004054 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004055 DeviceId: dh.DeviceID,
4056 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004057 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004058 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004059 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004060 return err
4061 }
mpagenkoe4782082021-11-25 12:04:26 +00004062 } else {
4063 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 +00004064 }
mpagenkoe4782082021-11-25 12:04:26 +00004065 dh.deviceReason = deviceReason
4066 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4067 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004068 return nil
4069}
4070
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
4072 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004073 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004074 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4075 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004076 }
mpagenkof1fc3862021-02-16 10:09:52 +00004077 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004078}
4079
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304080func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4081 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4082 if pDevEntry != nil {
4083 pDevEntry.MutexPersOnuConfig.Lock()
4084 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4085 pDevEntry.MutexPersOnuConfig.Unlock()
4086 } else {
4087 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4088 }
4089}
4090
4091func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4092 rebootFlag := false
4093 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4094 if pDevEntry != nil {
4095 pDevEntry.MutexPersOnuConfig.RLock()
4096 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4097 pDevEntry.MutexPersOnuConfig.RUnlock()
4098 } else {
4099 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4100 }
4101 return rebootFlag
4102}
4103
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004104// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004105// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004106func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4107 dh.lockDevice.RLock()
4108 defer dh.lockDevice.RUnlock()
4109 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004110 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004111 }
4112 return 0, errors.New("error-fetching-uni-port")
4113}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004114
4115// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004116func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4117 var errorsList []error
4118 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 -08004119
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004120 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4121 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4122 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4123
4124 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4125 // successfully.
4126 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4127 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4128 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004129 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 -08004130 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004131 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004133 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004134}
4135
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004136func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4137 var err error
4138 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004139 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004140
4141 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004142 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004143 errorsList = append(errorsList, err)
4144 }
4145 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004146 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004147
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004148 return errorsList
4149}
4150
4151func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4152 var err error
4153 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004154 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004155 // Check if group metric related config is updated
4156 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004157 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4158 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4159 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004160
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004161 if ok && m.Frequency != v.GroupFreq {
4162 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004163 errorsList = append(errorsList, err)
4164 }
4165 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004166 if ok && m.Enabled != v.Enabled {
4167 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004168 errorsList = append(errorsList, err)
4169 }
4170 }
4171 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004172 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004173 return errorsList
4174}
4175
4176func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4177 var err error
4178 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004179 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004180 // Check if standalone metric related config is updated
4181 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004182 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4183 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4184 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004185
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004186 if ok && m.Frequency != v.SampleFreq {
4187 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004188 errorsList = append(errorsList, err)
4189 }
4190 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191 if ok && m.Enabled != v.Enabled {
4192 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004193 errorsList = append(errorsList, err)
4194 }
4195 }
4196 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004197 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004198 return errorsList
4199}
4200
4201// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004202func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004203 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08004204
4205 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004206 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304207 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004208 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004209 // Initialize the next metric collection time.
4210 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4211 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004212 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004213 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304214 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4215 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004216 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304217
Girish Gowdrae09a6202021-01-12 18:10:59 -08004218 select {
4219 case <-dh.stopCollector:
4220 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004221 // Stop the L2 PM FSM
4222 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004223 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4224 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4225 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004226 }
4227 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004228 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004229 }
4230 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004231 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4232 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004233 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004234 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4235 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004236 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004237
Girish Gowdrae09a6202021-01-12 18:10:59 -08004238 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304239 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004240 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4241 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4242 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4243 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004244 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004245 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4246 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004247 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004248 } else {
4249 if dh.pmConfigs.Grouped { // metrics are managed as a group
4250 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004251 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004252
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004253 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4254 // 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 -08004255 // 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 +00004256 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4257 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004258 }
4259 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004260 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4261 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4262 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4263 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004264 }
4265 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004266 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004267
4268 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004269 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4270 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4271 // 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 -08004272 // 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 +00004273 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004274 prevInternal := g.NextCollectionInterval
4275 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004276 }
4277 }
4278 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004279 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4280 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4281 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004282 prevInternal := m.NextCollectionInterval
4283 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004284 }
4285 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004286 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004287 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004288 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004289 } */
4290 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004291 }
4292 }
4293}
kesavandfdf77632021-01-26 23:40:33 -05004294
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304295//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304296func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4297
4298 singleValResp := extension.SingleSetValueResponse{
4299 Response: &extension.SetValueResponse{
4300 Status: extension.SetValueResponse_OK,
4301 },
4302 }
4303
4304 return &singleValResp
4305}
4306
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004307func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004309 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4310 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004311}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004312
Himani Chawla43f95ff2021-06-03 00:24:12 +05304313func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4314 if dh.pOnuMetricsMgr == nil {
4315 return &extension.SingleGetValueResponse{
4316 Response: &extension.GetValueResponse{
4317 Status: extension.GetValueResponse_ERROR,
4318 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4319 },
4320 }
4321 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304322 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304323 return resp
4324}
4325
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004326func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4327
4328 var err error
4329 var pDevOmciCC *cmn.OmciCC
4330 if dh.pOnuOmciDevice == nil {
4331 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4332 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4333 } else {
4334 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4335 if pDevOmciCC == nil {
4336 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4337 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4338 }
4339 }
4340 if err != nil {
4341 return &extension.SingleGetValueResponse{
4342 Response: &extension.GetValueResponse{
4343 Status: extension.GetValueResponse_ERROR,
4344 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4345 },
4346 },
4347 err
4348 }
4349 return pDevOmciCC.GetOmciCounters(), nil
4350}
4351
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304352//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004353func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4354 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004355 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004356 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004357 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004358}
4359
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004360func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004361 var pAdapterFsm *cmn.AdapterFsm
4362 //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 +00004363 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004364 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004365 {
mpagenkofbf577d2021-10-12 11:44:33 +00004366 if dh.pOnuOmciDevice != nil {
4367 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4368 } else {
4369 return true //FSM not active - so there is no activity on omci
4370 }
mpagenkof1fc3862021-02-16 10:09:52 +00004371 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004372 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004373 {
mpagenkofbf577d2021-10-12 11:44:33 +00004374 if dh.pOnuOmciDevice != nil {
4375 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4376 } else {
4377 return true //FSM not active - so there is no activity on omci
4378 }
mpagenkof1fc3862021-02-16 10:09:52 +00004379 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004380 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004381 {
mpagenkofbf577d2021-10-12 11:44:33 +00004382 if dh.pLockStateFsm != nil {
4383 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4384 } else {
4385 return true //FSM not active - so there is no activity on omci
4386 }
mpagenkof1fc3862021-02-16 10:09:52 +00004387 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004388 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004389 {
mpagenkofbf577d2021-10-12 11:44:33 +00004390 if dh.pUnlockStateFsm != nil {
4391 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4392 } else {
4393 return true //FSM not active - so there is no activity on omci
4394 }
mpagenkof1fc3862021-02-16 10:09:52 +00004395 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004396 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004397 {
mpagenkofbf577d2021-10-12 11:44:33 +00004398 if dh.pOnuMetricsMgr != nil {
4399 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004400 } else {
4401 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004402 }
4403 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004404 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004405 {
4406 dh.lockUpgradeFsm.RLock()
4407 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004408 if dh.pOnuUpradeFsm != nil {
4409 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4410 } else {
4411 return true //FSM not active - so there is no activity on omci
4412 }
mpagenko80622a52021-02-09 16:53:23 +00004413 }
mpagenkof1fc3862021-02-16 10:09:52 +00004414 default:
4415 {
4416 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004417 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004418 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004419 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004420 }
mpagenkofbf577d2021-10-12 11:44:33 +00004421 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4422 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4423 }
4424 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004425}
4426
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004427func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4428 for _, v := range dh.pOnuTP.PAniConfigFsm {
4429 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004430 return false
4431 }
4432 }
4433 return true
4434}
4435
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304436//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004437func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004438 dh.lockVlanConfig.RLock()
4439 defer dh.lockVlanConfig.RUnlock()
4440 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004441 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004442 return false
4443 }
4444 }
4445 return true //FSM not active - so there is no activity on omci
4446}
4447
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304448//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004449func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4450 dh.lockVlanConfig.RLock()
4451 defer dh.lockVlanConfig.RUnlock()
4452 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004453 if v.PAdaptFsm.PFsm != nil {
4454 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004455 return true //there is at least one VLAN FSM with some active configuration
4456 }
4457 }
4458 }
4459 return false //there is no VLAN FSM with some active configuration
4460}
4461
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004462func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004463 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4464 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4465 return false
4466 }
4467 }
4468 // a further check is done to identify, if at least some data traffic related configuration exists
4469 // 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])
4470 return dh.checkUserServiceExists(ctx)
4471}
4472
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004473func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304474 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 +00004475 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004476 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004477 // TODO: fatal error reset ONU, delete deviceHandler!
4478 return
4479 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004480 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4481 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004482}
4483
4484func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4485 dh.mutexCollectorFlag.Lock()
4486 dh.collectorIsRunning = flagValue
4487 dh.mutexCollectorFlag.Unlock()
4488}
4489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004490func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004491 dh.mutexCollectorFlag.RLock()
4492 flagValue := dh.collectorIsRunning
4493 dh.mutexCollectorFlag.RUnlock()
4494 return flagValue
4495}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304496
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304497func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4498 dh.mutextAlarmManagerFlag.Lock()
4499 dh.alarmManagerIsRunning = flagValue
4500 dh.mutextAlarmManagerFlag.Unlock()
4501}
4502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004503func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304504 dh.mutextAlarmManagerFlag.RLock()
4505 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004506 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304507 dh.mutextAlarmManagerFlag.RUnlock()
4508 return flagValue
4509}
4510
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004511func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004512 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304513
4514 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004515 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304516 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304517 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304518 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304519 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004520 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4521 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304522 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304523 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004524 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4525 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304526 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304527 }
4528}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004529
Girish Gowdrae95687a2021-09-08 16:30:58 -07004530func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4531 dh.mutexFlowMonitoringRoutineFlag.Lock()
4532 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004533 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004534 dh.isFlowMonitoringRoutineActive[uniID] = flag
4535}
4536
4537func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4538 dh.mutexFlowMonitoringRoutineFlag.RLock()
4539 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4540 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004541 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304542 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4543 return dh.isFlowMonitoringRoutineActive[uniID]
4544 }
4545 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004546}
4547
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004548func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304549 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004550
Maninder7961d722021-06-16 22:10:28 +05304551 connectStatus := voltha.ConnectStatus_UNREACHABLE
4552 operState := voltha.OperStatus_UNKNOWN
4553
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004554 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004555 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004556 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004557 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004558 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004559 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304560 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004561 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4562 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4563 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4564 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4565 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4566 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4567 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4568 // However, a later refactoring of the functionality remains unaffected.
4569 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004570 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004571 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304572 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004573 log.Fields{"device-id": dh.DeviceID})
akashreddykb03dde02025-12-02 10:53:18 +05304574 } else if !onuDevEntry.SOnuPersistentData.PersRebootInProgress {
mpagenko2c3f6c52021-11-23 11:22:10 +00004575 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304576 switch onuDevEntry.SOnuPersistentData.PersOperState {
4577 case "up":
Maninderb5187552021-03-23 22:23:42 +05304578 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004579 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4580 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304581 operState = voltha.OperStatus_ACTIVE
4582 } else {
4583 operState = voltha.OperStatus_ACTIVATING
4584 }
4585 }
mgoudad611f4c2025-10-30 14:49:27 +05304586 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304587 operState = voltha.OperStatus_DISCOVERED
4588 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004589 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004590 logger.Debugw(ctx, "Core DeviceStateUpdate",
4591 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304592 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304593 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004594 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004595 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004596 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004597 ConnStatus: connectStatus,
4598 OperStatus: operState,
4599 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304600 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004601 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304602 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004603 } else {
Maninderb5187552021-03-23 22:23:42 +05304604 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004605 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304606
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004607 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304608 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004609 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004610 } else {
4611 onuDevEntry.MutexPersOnuConfig.RLock()
4612 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4613 connectStatus = voltha.ConnectStatus_REACHABLE
4614 }
4615 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304616 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004617 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004618 }
mpagenko101ac942021-11-16 15:01:29 +00004619 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004620 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004621 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004622 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004624 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304625 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004626 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004627 } else {
4628 onuDevEntry.MutexPersOnuConfig.RLock()
4629 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4630 connectStatus = voltha.ConnectStatus_REACHABLE
4631 }
4632 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304633 }
4634
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004635 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304636
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004637 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004638 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004639 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004640 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004641 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004642
4643 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4644 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4645 } else {
4646 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304647 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004648 onuDevEntry.MutexReconciledTpInstances.Unlock()
4649 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004650 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004651 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004652 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304653 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004654 dh.reconciling = cSkipOnuConfigReconciling
4655 } else {
4656 dh.reconciling = cOnuConfigReconciling
4657 }
4658 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004659}
4660
mpagenko101ac942021-11-16 15:01:29 +00004661func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304662 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004663 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004664 dh.sendChReconcileFinished(success)
4665 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4666 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4667 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004668 } else {
mpagenko101ac942021-11-16 15:01:29 +00004669 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004670 }
4671}
4672
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004673func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004674 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004675 defer dh.mutexReconcilingFlag.RUnlock()
4676 return dh.reconciling != cNoReconciling
4677}
4678
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004679func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004680 dh.mutexReconcilingFlag.RLock()
4681 defer dh.mutexReconcilingFlag.RUnlock()
4682 return dh.reconciling == cSkipOnuConfigReconciling
4683}
4684
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004685func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4686 dh.mutexReconcilingFirstPassFlag.Lock()
4687 dh.reconcilingFirstPass = value
4688 dh.mutexReconcilingFirstPassFlag.Unlock()
4689}
4690
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004691func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4692 dh.mutexReconcilingReasonUpdate.Lock()
4693 dh.reconcilingReasonUpdate = value
4694 dh.mutexReconcilingReasonUpdate.Unlock()
4695}
4696
4697func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4698 dh.mutexReconcilingReasonUpdate.RLock()
4699 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4700 return dh.reconcilingReasonUpdate
4701}
4702
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004703func (dh *deviceHandler) getDeviceReason() uint8 {
4704 dh.mutexDeviceReason.RLock()
4705 value := dh.deviceReason
4706 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004707 return value
4708}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004709
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004710func (dh *deviceHandler) GetDeviceReasonString() string {
4711 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004712}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004713
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004714func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004715 dh.mutexReadyForOmciConfig.Lock()
4716 dh.readyForOmciConfig = flagValue
4717 dh.mutexReadyForOmciConfig.Unlock()
4718}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004719func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004720 dh.mutexReadyForOmciConfig.RLock()
4721 flagValue := dh.readyForOmciConfig
4722 dh.mutexReadyForOmciConfig.RUnlock()
4723 return flagValue
4724}
Maninder7961d722021-06-16 22:10:28 +05304725
4726func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004727 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304728 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004729 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304730 }
4731
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004732 logger.Debugw(ctx, "Core DeviceStateUpdate",
4733 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004734 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004735 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004736 ConnStatus: connectStatus,
4737 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4738 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304739 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004740 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304741 }
4742}
khenaidoo7d3c5582021-08-11 18:09:44 -04004743
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304744func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4745 if techProfInstLoadFailed {
4746 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4747 logger.Errorw(ctx, "unable to update device reason to core",
4748 log.Fields{"device-id": dh.DeviceID, "Err": err})
4749 }
4750 context := make(map[string]string)
4751 context["device-id"] = dh.DeviceID
4752 context["onu-serial-number"] = dh.device.SerialNumber
4753 context["parent-id"] = dh.parentID
4754
4755 // Send event on flow configuration failure so that corrective action can be triggered from NB
4756 deviceEvent := &voltha.DeviceEvent{
4757 ResourceId: dh.DeviceID,
4758 DeviceEventName: cmn.OnuFlowConfigFailed,
4759 Description: cmn.OnuFlowConfigFailedDesc,
4760 Context: context,
4761 }
4762 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4763 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4764 }
4765}
4766
khenaidoo7d3c5582021-08-11 18:09:44 -04004767/*
4768Helper functions to communicate with Core
4769*/
4770
4771func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4772 cClient, err := dh.coreClient.GetCoreServiceClient()
4773 if err != nil || cClient == nil {
4774 return nil, err
4775 }
4776 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4777 defer cancel()
4778 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304779 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004780}
4781
khenaidoo42dcdfd2021-10-19 17:34:12 -04004782func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004783 cClient, err := dh.coreClient.GetCoreServiceClient()
4784 if err != nil || cClient == nil {
4785 return err
4786 }
4787 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4788 defer cancel()
4789 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004790 logger.Debugw(subCtx, "device-updated-in-core",
4791 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004792 return err
4793}
4794
4795func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4796 cClient, err := dh.coreClient.GetCoreServiceClient()
4797 if err != nil || cClient == nil {
4798 return err
4799 }
4800 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4801 defer cancel()
4802 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004803 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4804 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004805 return err
4806}
4807
4808func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4809 cClient, err := dh.coreClient.GetCoreServiceClient()
4810 if err != nil || cClient == nil {
4811 return err
4812 }
4813 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4814 defer cancel()
4815 _, err = cClient.DeviceUpdate(subCtx, device)
4816 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4817 return err
4818}
4819
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004820func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004821 cClient, err := dh.coreClient.GetCoreServiceClient()
4822 if err != nil || cClient == nil {
4823 return err
4824 }
4825 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4826 defer cancel()
4827 _, err = cClient.PortCreated(subCtx, port)
4828 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4829 return err
4830}
4831
khenaidoo42dcdfd2021-10-19 17:34:12 -04004832func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004833 cClient, err := dh.coreClient.GetCoreServiceClient()
4834 if err != nil || cClient == nil {
4835 return err
4836 }
4837 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4838 defer cancel()
4839 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004840 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 -04004841 return err
4842}
4843
khenaidoo42dcdfd2021-10-19 17:34:12 -04004844func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004845 cClient, err := dh.coreClient.GetCoreServiceClient()
4846 if err != nil || cClient == nil {
4847 return err
4848 }
4849 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4850 defer cancel()
4851 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004852 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 -04004853 return err
4854}
4855
4856/*
4857Helper functions to communicate with parent adapter
4858*/
4859
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004860func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4861 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4862
4863 var request = ia.TechProfileInstanceRequestMessage{
4864 DeviceId: dh.DeviceID,
4865 TpInstancePath: aTpPath,
4866 ParentDeviceId: dh.parentID,
4867 ParentPonPort: dh.device.ParentPortNo,
4868 OnuId: dh.device.ProxyAddress.OnuId,
4869 UniId: uint32(aUniID),
4870 }
4871
4872 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004873 if err != nil || pgClient == nil {
4874 return nil, err
4875 }
4876 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4877 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004878 logger.Debugw(subCtx, "get-tech-profile-instance",
4879 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004880 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004881}
4882
Girish Gowdrae95687a2021-09-08 16:30:58 -07004883// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4884// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4885func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4886 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4887 dh.setFlowMonitoringIsRunning(uniID, true)
4888 for {
4889 select {
4890 // block on the channel to receive an incoming flow
4891 // process the flow completely before proceeding to handle the next flow
4892 case flowCb := <-dh.flowCbChan[uniID]:
4893 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304894 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004895 respChan := make(chan error)
4896 if flowCb.addFlow {
4897 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4898 } else {
4899 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4900 }
4901 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304902 select {
4903
4904 case msg := <-respChan:
4905 *flowCb.respChan <- msg
4906 // response sent successfully
4907 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4908 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4909 case <-flowCb.ctx.Done():
4910 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4911 // Optionally, you can handle cleanup or logging here
4912 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4913 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4914 if pVlanFilterStatemachine != nil {
4915
4916 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4917 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
4918 log.Fields{"device-id": dh.DeviceID, "err": err})
4919
4920 }
4921
4922 }
4923 }
4924
4925 ctx2 := context.Background()
4926 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
4927 if metadata == 0 {
4928 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
4929 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4930 continue
4931 }
4932 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
4933
4934 if TpID == uint16(0) {
4935 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
4936 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4937 continue
4938 }
4939 if dh.pOnuTP != nil {
4940 // should always be the case here
4941 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
4942 if dh.pOnuTP.PAniConfigFsm != nil {
4943 uniTP := avcfg.UniTP{
4944 UniID: flowCb.uniPort.UniID,
4945 TpID: uint8(TpID),
4946 }
4947 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
4948 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
4949 }
4950 }
4951 }
4952
4953 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07004954 case <-dh.stopFlowMonitoringRoutine[uniID]:
4955 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4956 dh.setFlowMonitoringIsRunning(uniID, false)
4957 return
4958 }
4959 }
4960}
4961
kesavand011d5162021-11-25 19:21:06 +05304962func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4963 request.ParentDeviceId = dh.GetProxyAddressID()
4964 request.ChildDeviceId = dh.DeviceID
4965 request.ProxyAddress = dh.GetProxyAddress()
4966 request.ConnectStatus = common.ConnectStatus_REACHABLE
4967
4968 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4969 if err != nil || pgClient == nil {
4970 return err
4971 }
4972 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4973 defer cancel()
4974 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4975 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4976 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004977 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4978 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304979 }
4980 return err
4981}
4982
khenaidoo42dcdfd2021-10-19 17:34:12 -04004983func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004984 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4985 if err != nil || pgClient == nil {
4986 return err
4987 }
4988 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4989 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004990 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004991 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004992 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4993 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004994 if status.Code(err) == codes.Unavailable {
4995 dh.setOltAvailable(false)
4996 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004997 logger.Errorw(ctx, "omci-failure",
4998 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004999 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04005000 }
5001 return err
5002}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005003
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005004func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
5005 // Check if there are additional TCONT instances necessary/available
5006 pDevEntry.MutexPersOnuConfig.Lock()
5007 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
5008 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
5009 pDevEntry.MutexPersOnuConfig.Unlock()
5010 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
5011 logger.Debugw(ctx, "checking available TCONT instances",
5012 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
5013 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
5014 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
5015 log.Fields{"device-id": dh.device.Id})
5016 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305017 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005018 }
5019 } else {
5020 pDevEntry.MutexPersOnuConfig.Unlock()
5021 }
5022 // Check if there are enough PrioQueue instances available
5023 if dh.pOnuTP != nil {
5024 var numberOfUsPrioQueueDbInsts int
5025
5026 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
5027 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305028 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00005029 numberOfUsPrioQueueDbInsts++
5030 }
5031 }
5032 // Check if there is an upstream PriorityQueue instance available for each Gem port
5033 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5034 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5035 log.Fields{"device-id": dh.DeviceID,
5036 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5037 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5038 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5039
5040 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5041 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5042 log.Fields{"device-id": dh.device.Id})
5043 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305044 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 +00005045 }
5046 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5047 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5048 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5049 } else {
5050 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5051 log.Fields{"device-id": dh.DeviceID})
5052 }
5053 return nil
5054}
5055
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005056// GetDeviceID - TODO: add comment
5057func (dh *deviceHandler) GetDeviceID() string {
5058 return dh.DeviceID
5059}
5060
5061// GetProxyAddressID - TODO: add comment
5062func (dh *deviceHandler) GetProxyAddressID() string {
5063 return dh.device.ProxyAddress.GetDeviceId()
5064}
5065
5066// GetProxyAddressType - TODO: add comment
5067func (dh *deviceHandler) GetProxyAddressType() string {
5068 return dh.device.ProxyAddress.GetDeviceType()
5069}
5070
5071// GetProxyAddress - TODO: add comment
5072func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5073 return dh.device.ProxyAddress
5074}
5075
5076// GetEventProxy - TODO: add comment
5077func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5078 return dh.EventProxy
5079}
5080
5081// GetOmciTimeout - TODO: add comment
5082func (dh *deviceHandler) GetOmciTimeout() int {
5083 return dh.pOpenOnuAc.omciTimeout
5084}
5085
5086// GetAlarmAuditInterval - TODO: add comment
5087func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5088 return dh.pOpenOnuAc.alarmAuditInterval
5089}
5090
5091// GetDlToOnuTimeout4M - TODO: add comment
5092func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5093 return dh.pOpenOnuAc.dlToOnuTimeout4M
5094}
5095
5096// GetUniEntityMap - TODO: add comment
5097func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5098 return &dh.uniEntityMap
5099}
5100
5101// GetPonPortNumber - TODO: add comment
5102func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5103 return &dh.ponPortNumber
5104}
5105
5106// GetUniVlanConfigFsm - TODO: add comment
5107func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005108 dh.lockVlanConfig.RLock()
5109 value := dh.UniVlanConfigFsmMap[uniID]
5110 dh.lockVlanConfig.RUnlock()
5111 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005112}
5113
5114// GetOnuAlarmManager - TODO: add comment
5115func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5116 return dh.pAlarmMgr
5117}
5118
5119// GetOnuMetricsManager - TODO: add comment
5120func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5121 return dh.pOnuMetricsMgr
5122}
5123
5124// GetOnuTP - TODO: add comment
5125func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5126 return dh.pOnuTP
5127}
5128
5129// GetBackendPathPrefix - TODO: add comment
5130func (dh *deviceHandler) GetBackendPathPrefix() string {
5131 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5132}
5133
5134// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305135func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005136 return dh.pOnuIndication
5137}
5138
5139// RLockMutexDeletionInProgressFlag - TODO: add comment
5140func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5141 dh.mutexDeletionInProgressFlag.RLock()
5142}
5143
5144// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5145func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5146 dh.mutexDeletionInProgressFlag.RUnlock()
5147}
5148
5149// GetDeletionInProgress - TODO: add comment
5150func (dh *deviceHandler) GetDeletionInProgress() bool {
5151 return dh.deletionInProgress
5152}
5153
5154// GetPmConfigs - TODO: add comment
5155func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5156 return dh.pmConfigs
5157}
5158
5159// GetDeviceType - TODO: add comment
5160func (dh *deviceHandler) GetDeviceType() string {
5161 return dh.DeviceType
5162}
5163
5164// GetLogicalDeviceID - TODO: add comment
5165func (dh *deviceHandler) GetLogicalDeviceID() string {
5166 return dh.logicalDeviceID
5167}
5168
5169// GetDevice - TODO: add comment
5170func (dh *deviceHandler) GetDevice() *voltha.Device {
5171 return dh.device
5172}
5173
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005174func (dh *deviceHandler) setOltAvailable(value bool) {
5175 dh.mutexOltAvailable.Lock()
5176 dh.oltAvailable = value
5177 dh.mutexOltAvailable.Unlock()
5178}
5179
5180// IsOltAvailable - TODO: add comment
5181func (dh *deviceHandler) IsOltAvailable() bool {
5182 dh.mutexOltAvailable.RLock()
5183 defer dh.mutexOltAvailable.RUnlock()
5184 return dh.oltAvailable
5185}
5186
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005187// GetMetricsEnabled - TODO: add comment
5188func (dh *deviceHandler) GetMetricsEnabled() bool {
5189 return dh.pOpenOnuAc.MetricsEnabled
5190}
5191
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005192// GetExtendedOmciSupportEnabled - TODO: add comment
5193func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5194 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5195}
5196
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305197// GetExtendedOmciSupportEnabled - TODO: add comment
5198func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5199 return dh.pOpenOnuAc.skipOnuConfig
5200}
5201
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305202func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5203 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5204}
5205
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005206// InitPmConfigs - TODO: add comment
5207func (dh *deviceHandler) InitPmConfigs() {
5208 dh.pmConfigs = &voltha.PmConfigs{}
5209}
5210
5211// GetUniPortMask - TODO: add comment
5212func (dh *deviceHandler) GetUniPortMask() int {
5213 return dh.pOpenOnuAc.config.UniPortMask
5214}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005215
5216func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5217 tpPathFound := false
5218 for _, tpPath := range aTpPathMap {
5219 if tpPath != "" {
5220 tpPathFound = true
5221 }
5222 }
5223 return tpPathFound
5224}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005225
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305226func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5227 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5228 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5229 return resp
5230}
5231
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305232// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5233func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5234 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305235 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5236 return resp
5237}
5238
5239// getOnuFECStats - Get the GEM PM history data of the request ONT device
5240func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5241 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5242 logger.Debugw(ctx, "Received response from ONU Metrics Manager for FEC Stats", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305243 return resp
5244}
5245
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305246func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5247 return dh.deviceDeleteCommChan
5248}
5249
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005250// PrepareForGarbageCollection - remove references to prepare for garbage collection
5251func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5252 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5253
5254 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5255 // first let the objects rest for some time to give all asynchronously started
5256 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005257 time.Sleep(2 * time.Second)
5258
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005259 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005260
5261 if dh.pOnuTP != nil {
5262 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5263 }
5264 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005265 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5266 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005267 select {
5268 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5269 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5270 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5271 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005272 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005273 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005274 }
5275 if dh.pAlarmMgr != nil {
5276 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5277 }
5278 if dh.pSelfTestHdlr != nil {
5279 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5280 }
5281 if dh.pLockStateFsm != nil {
5282 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5283 }
5284 if dh.pUnlockStateFsm != nil {
5285 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5286 }
5287 if dh.pOnuUpradeFsm != nil {
5288 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5289 }
5290 if dh.pOnuOmciDevice != nil {
5291 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5292 }
5293 for k, v := range dh.UniVlanConfigFsmMap {
5294 v.PrepareForGarbageCollection(ctx, aDeviceID)
5295 delete(dh.UniVlanConfigFsmMap, k)
5296 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305297 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005298 dh.pOnuOmciDevice = nil
5299 dh.pOnuTP = nil
5300 dh.pOnuMetricsMgr = nil
5301 dh.pAlarmMgr = nil
5302 dh.pSelfTestHdlr = nil
5303 dh.pLockStateFsm = nil
5304 dh.pUnlockStateFsm = nil
5305 dh.pOnuUpradeFsm = nil
5306}