blob: cbb9acdc3dec0c249764484c86bb15620e5d2d62 [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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 pDevEntry.MutexPersOnuConfig.RLock()
887 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
888 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
889 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
890 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
891 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000893}
894
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000895func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530896 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000897
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000898 continueWithFlowConfig := false
899
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000900 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000901 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000902 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000903 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
904 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 dh.pOnuTP.LockTpProcMutex()
907 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000908
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000910 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
912 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530913 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000915 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
916 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000917 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700919 techProfsFound := false
920 techProfInstLoadFailed := false
921outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000922 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000923 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000924 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000925 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000927 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000928 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000929 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
931 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000932 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000934 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700935 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 var iaTechTpInst ia.TechProfileDownloadMessage
937 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800938 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000939 pDevEntry.MutexReconciledTpInstances.RLock()
940 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
941 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000942 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000943 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000945 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 break outerLoop
947 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000948 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000949 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 var tpInst tech_profile.TechProfileInstance
951 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400952 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000954 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000957 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700959 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
960 break outerLoop
961 }
962
Girish Gowdra041dcb32020-11-16 16:54:30 -0800963 // deadline context to ensure completion of background routines waited for
964 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
965 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000967
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800969 var wg sync.WaitGroup
970 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
974 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700975 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
976 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800977 }
mpagenko2dc896e2021-08-02 12:03:59 +0000978 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 if len(uniData.PersFlowParams) != 0 {
980 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000981 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000983 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 } // for all UNI entries from SOnuPersistentData
985 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
986 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000987 }
mpagenko2dc896e2021-08-02 12:03:59 +0000988
989 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
990 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000991
992 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000993}
994
995func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
996 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
997 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530998 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001000 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 return
1002 }
mpagenko2dc896e2021-08-02 12:03:59 +00001003 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001004 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001005 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001006 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001008 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009 }
mpagenko2dc896e2021-08-02 12:03:59 +00001010 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301011 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001013 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001014 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015}
1016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1018 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001021 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001022 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001023 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001024 return
1025 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001026
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001027 pDevEntry.MutexPersOnuConfig.RLock()
1028 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1029 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301030 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001032 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001033 return
1034 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001036 var uniVlanConfigEntries []uint8
1037 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001040 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1041 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001044 continue
1045 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001046 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001047 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001048 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001049 // It doesn't make sense to configure any flows if no TPs are available
1050 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001051 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1053 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001054 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001056
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001059 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001061 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1062 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001063 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064 return
1065 }
mpagenko101ac942021-11-16 15:01:29 +00001066 //needed to split up function due to sca complexity
1067 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1068
mpagenko2dc896e2021-08-02 12:03:59 +00001069 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001070 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001071 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1072 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001073 // this can't be used as global finished reconciling flag because
1074 // assumes is getting called before the state machines for the last flow is completed,
1075 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001076 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1077 } // for all UNI entries from SOnuPersistentData
1078 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001079
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001080 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301081 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001083 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001084 return
1085 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001086 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1087 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1088 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1089 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1090 log.Fields{"device-id": dh.DeviceID})
1091 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1092 if pDevEntry != nil {
1093 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001094 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001095 } else {
1096 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1097 log.Fields{"device-id": dh.DeviceID})
1098 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1099 if pDevEntry != nil {
1100 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1101 }
1102 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001104 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001105}
1106
mpagenko101ac942021-11-16 15:01:29 +00001107func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1108 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1109 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1110 flowsProcessed := 0
1111 lastFlowToReconcile := false
1112 loUniID := apUniPort.UniID
1113 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001114 if !(*apFlowsFound) {
1115 *apFlowsFound = true
1116 syncChannel := make(chan struct{})
1117 // start go routine with select() on reconciling vlan config channel before
1118 // starting vlan config reconciling process to prevent loss of any signal
1119 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1120 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1121 //block until the wait routine is really blocked on channel input
1122 // in order to prevent to early ready signal from VlanConfig processing
1123 <-syncChannel
1124 }
1125 if flowsProcessed == len(aPersFlowParam)-1 {
1126 var uniAdded bool
1127 lastFlowToReconcile = true
1128 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1129 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001130 }
1131 }
mpagenko101ac942021-11-16 15:01:29 +00001132 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1133 "device-id": dh.DeviceID, "uni-id": loUniID,
1134 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1135 dh.lockVlanConfig.Lock()
1136 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1137 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1138 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301139 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 +00001140 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1141 }
1142 } else {
1143 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301144 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301145 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, false, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001146 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1147 }
1148 }
1149 dh.lockVlanConfig.Unlock()
1150 flowsProcessed++
1151 } //for all flows of this UNI
1152}
1153
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301154// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1155//
1156// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001157func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1158 waitGroup *cmn.WaitGroupWithTimeOut) {
1159 var reconciledUniVlanConfigEntries []uint8
1160 var appended bool
1161 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1162 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1163 "device-id": dh.DeviceID, "expiry": expiry})
1164 // indicate blocking on channel now to the caller
1165 aSyncChannel <- struct{}{}
1166 for {
1167 select {
1168 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1169 switch uniIndication {
1170 // no activity requested (should normally not be received) - just continue waiting
1171 case cWaitReconcileFlowNoActivity:
1172 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1173 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301174 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001175 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1176 return
1177 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1178 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301179 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001180 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1181 return
1182 // this should be a valid UNI vlan config done indication
1183 default:
1184 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301185 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001186 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1187 if reconciledUniVlanConfigEntries, appended =
1188 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1189 waitGroup.Done()
1190 }
1191 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301192 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 +00001193 }
1194 } //switch uniIndication
1195
1196 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1197 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1198 log.Fields{"device-id": dh.DeviceID})
1199 return
1200 }
1201 }
1202}
1203
1204func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1205 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1206}
1207
1208func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1209 for _, ele := range slice {
1210 if ele == val {
1211 return slice, false
1212 }
1213 }
1214 return append(slice, val), true
1215}
1216
1217// sendChReconcileFinished - sends true or false on reconcileFinish channel
1218func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1219 if dh != nil { //if the object still exists (might have been already deleted in background)
1220 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1221 select {
1222 case dh.chReconcilingFinished <- success:
1223 default:
1224 }
1225 }
1226}
1227
1228// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1229func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1230 if dh != nil { //if the object still exists (might have been already deleted in background)
1231 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1232 select {
1233 case dh.chUniVlanConfigReconcilingDone <- value:
1234 default:
1235 }
1236 }
1237}
1238
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301239func (dh *deviceHandler) DeviceFlowConfigOnReboot(ctx context.Context) {
1240 logger.Debugw(ctx, "rebooting - trigger flow config", log.Fields{"device-id": dh.DeviceID})
1241
1242 defer dh.UpdateAndStoreRebootState(ctx, false)
1243 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1244 if pDevEntry == nil {
1245 logger.Errorw(ctx, "rebooting - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1246 return
1247 }
1248
1249 pDevEntry.MutexPersOnuConfig.RLock()
1250 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1251 pDevEntry.MutexPersOnuConfig.RUnlock()
1252 logger.Warn(ctx, "rebooting - no uni-configs have been stored - aborting",
1253 log.Fields{"device-id": dh.DeviceID})
1254 return
1255 }
1256 flowsFound := false
1257 var uniVlanConfigEntries []uint8
1258 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1259
1260 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1261 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1262 if len(uniData.PersFlowParams) == 0 {
1263 logger.Debugw(ctx, "rebooting - no flows stored for uniID",
1264 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1265 continue
1266 }
1267 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1268 logger.Warnw(ctx, "rebooting - but no TPs stored for uniID, abort",
1269 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1270 // It doesn't make sense to configure any flows if no TPs are available
1271 continue
1272 }
1273 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1274 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1275 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1276 pDevEntry.MutexPersOnuConfig.RUnlock()
1277
1278 var uniPort *cmn.OnuUniPort
1279 var exist bool
1280 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
1281 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
1282 logger.Errorw(ctx, "rebooting - OnuUniPort data not found - terminate flow config",
1283 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1284 return
1285 }
1286
1287 dh.updateOnRebootFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1288
1289 logger.Debugw(ctx, "rebooting - flows processed", log.Fields{
1290 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
1291 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1292 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
1293 // this can't be used as global finished reconciling flag because
1294 // assumes is getting called before the state machines for the last flow is completed,
1295 // while this is not guaranteed.
1296 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1297 } // for all UNI entries from SOnuPersistentData
1298 pDevEntry.MutexPersOnuConfig.RUnlock()
1299
1300 if !flowsFound {
1301 logger.Warn(ctx, "rebooting - no flows have been stored before device reboot - terminate flow config",
1302 log.Fields{"device-id": dh.DeviceID})
1303 return
1304 }
1305 logger.Debugw(ctx, "rebooting - waiting on ready indication of requested UNIs", log.Fields{
1306 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1307 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1308 logger.Debugw(ctx, "rebooting - flow config for all UNI's has been finished in time",
1309 log.Fields{"device-id": dh.DeviceID})
1310 } else {
1311 logger.Errorw(ctx, "rebooting - timeout waiting for flow config for all UNI's to be finished!",
1312 log.Fields{"device-id": dh.DeviceID})
1313 return
1314 }
1315}
1316
1317func (dh *deviceHandler) UpdateAndStoreRebootState(ctx context.Context, flag bool) {
1318 dh.UpdateRebootPersData(ctx, flag)
1319 if err := dh.StorePersistentData(ctx); err != nil {
1320 logger.Errorw(ctx, "rebooting - failed to store persistent data in kv store", log.Fields{"device-id": dh.DeviceID})
1321 }
1322}
1323
1324func (dh *deviceHandler) updateOnRebootFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1325 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1326 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1327 flowsProcessed := 0
1328 lastFlowToConfigOnReboot := false
1329 loUniID := apUniPort.UniID
1330 for _, flowData := range aPersFlowParam {
1331 if !(*apFlowsFound) {
1332 *apFlowsFound = true
1333 syncChannel := make(chan struct{})
1334 // start go routine with select() on reconciling vlan config channel before
1335 // starting vlan config reconciling process to prevent loss of any signal
1336 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1337 go dh.waitOnUniVlanConfigOnRebootReady(ctx, syncChannel, apWaitGroup)
1338 //block until the wait routine is really blocked on channel input
1339 // in order to prevent to early ready signal from VlanConfig processing
1340 <-syncChannel
1341 }
1342 if flowsProcessed == len(aPersFlowParam)-1 {
1343 var uniAdded bool
1344 lastFlowToConfigOnReboot = true
1345 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1346 apWaitGroup.Add(1) //increment the waiting group
1347 }
1348 }
1349 logger.Debugw(ctx, "rebooting - add flow with cookie slice", log.Fields{
1350 "device-id": dh.DeviceID, "uni-id": loUniID,
1351 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1352 dh.lockVlanConfig.Lock()
1353 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1354 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1355 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1356 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 {
1357 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1358 }
1359 } else {
1360 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1361 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
1362 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, false, lastFlowToConfigOnReboot, flowData.Meter, nil); err != nil {
1363 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1364 }
1365 }
1366 dh.lockVlanConfig.Unlock()
1367 flowsProcessed++
1368 } //for all flows of this UNI
1369}
1370
1371func (dh *deviceHandler) waitOnUniVlanConfigOnRebootReady(ctx context.Context, aSyncChannel chan<- struct{},
1372 waitGroup *cmn.WaitGroupWithTimeOut) {
1373 var rebootUniVlanConfigEntries []uint8
1374 var appended bool
1375 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1376 logger.Debugw(ctx, "start waiting on vlanConfig ready indications on reboot", log.Fields{
1377 "device-id": dh.DeviceID, "expiry": expiry})
1378 // indicate blocking on channel now to the caller
1379 aSyncChannel <- struct{}{}
1380 for {
1381 select {
1382 case <-dh.deviceDeleteCommChan:
1383 // Cancel the context and return
1384 logger.Warnw(ctx, "Device Deletion invoked , stop further processing ", log.Fields{"device-id": dh.DeviceID})
1385 return
1386
1387 case uniIndication := <-dh.chUniVlanConfigOnRebootDone:
1388 switch uniIndication {
1389 // this should be a valid UNI vlan config done indication
1390 default:
1391 if uniIndication < platform.MaxUnisPerOnu {
1392 logger.Info(ctx, "rebooting - configuring flows has been finished in time for this UNI",
1393 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1394 if rebootUniVlanConfigEntries, appended =
1395 dh.appendIfMissing(rebootUniVlanConfigEntries, uint8(uniIndication)); appended {
1396 waitGroup.Done()
1397 }
1398 } else {
1399 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1400 }
1401 } //switch uniIndication
1402
1403 case <-time.After(expiry):
1404 logger.Errorw(ctx, "timeout waiting for configuring all UNI flows to be finished!",
1405 log.Fields{"device-id": dh.DeviceID})
1406 return
1407 }
1408 }
1409}
1410
1411func (dh *deviceHandler) SendChUniVlanConfigFinishedOnReboot(value uint16) {
1412 if dh != nil { //if the object still exists (might have been already deleted in background)
1413 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1414 select {
1415 case dh.chUniVlanConfigOnRebootDone <- value:
1416 default:
1417 }
1418 }
1419}
1420
1421func (dh *deviceHandler) CheckForDeviceTechProf(ctx context.Context) bool {
1422 logger.Info(ctx, "Check for tech profile config", log.Fields{"device-id": dh.DeviceID})
1423 techProfInstLoadFailed := false
1424 continueWithFlowConfig := false
1425 defer dh.UpdateAndStoreRebootState(ctx, continueWithFlowConfig)
1426 // Stop any on going reconciling thread as the flow configuration post reboot will be performed here
1427 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
1428
1429 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
1430 if pDevEntry == nil {
1431 logger.Errorw(ctx, "no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1432 return continueWithFlowConfig
1433 }
1434 dh.lockDevice.RLock()
1435 if dh.pOnuTP == nil {
1436 //should normally not happen ...
1437 logger.Warnw(ctx, "onuTechProf instance not set up - ignoring request",
1438 log.Fields{"device-id": dh.DeviceID})
1439 dh.lockDevice.RUnlock()
1440 return continueWithFlowConfig
1441 }
1442
1443 dh.pOnuTP.LockTpProcMutex()
1444 defer dh.pOnuTP.UnlockTpProcMutex()
1445 defer dh.lockDevice.RUnlock()
1446
1447 pDevEntry.MutexPersOnuConfig.RLock()
1448 persMutexLock := true
1449 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1450 pDevEntry.MutexPersOnuConfig.RUnlock()
1451 logger.Info(ctx, "no uni-configs have been stored - aborting",
1452 log.Fields{"device-id": dh.DeviceID})
1453 return continueWithFlowConfig
1454 }
1455
1456outerLoop:
1457 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
1458 uniID := uniData.PersUniID
1459
1460 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
1461 logger.Debugw(ctx, "no TPs stored for uniID",
1462 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
1463 continue
1464 }
1465 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
1466 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
1467 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1468 pDevEntry.MutexPersOnuConfig.RUnlock()
1469 persMutexLock = false
1470 for tpID, tpPath := range uniData.PersTpPathMap {
1471 if tpPath != "" {
1472 logger.Infow(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1473 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1474 })
1475 // Attempt the initial call before entering the retry loop
1476 iaTechTpInst, err := dh.GetTechProfileInstanceFromParentAdapter(ctx, uniID, tpPath)
1477 if err != nil {
1478 logger.Warnw(ctx, "Starting retrieval for TechProfileInstance", log.Fields{
1479 "uniID": uniID, "tpID": tpID, "tpPath": tpPath, "device-id": dh.DeviceID,
1480 })
1481 techProfInstLoadFailed = true
1482 break outerLoop
1483 }
1484 if iaTechTpInst != nil {
1485 var tpInst tech_profile.TechProfileInstance
1486 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
1487 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
1488 tpInst = *techTpInst.TpInstance
1489 logger.Debugw(ctx, "received-tp-instance-successfully-after-reboot", log.Fields{
1490 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1491 default: // do not support epon or other tech
1492 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
1493 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
1494 techProfInstLoadFailed = true
1495 break outerLoop
1496 }
1497
1498 continueWithFlowConfig = true
1499 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
1500 dctx, cancel := context.WithDeadline(ctx, deadline)
1501
1502 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
1503 var wg sync.WaitGroup
1504 wg.Add(1) // for the 1 go routine to finish
1505 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
1506 // Wait for either completion or cancellation
1507 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwldDuringReboot")
1508 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
1509 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.DeviceID, "err": tpErr, "tp-path": uniData.PersTpPathMap[tpID]})
1510 techProfInstLoadFailed = true
1511 continueWithFlowConfig = false
1512 break outerLoop
1513 }
1514 } else {
1515 logger.Errorw(ctx, "Tp instance is not valid", log.Fields{"tp-id": tpID, "tpPath": tpPath, "device-id": dh.DeviceID, "err": err})
1516 techProfInstLoadFailed = true
1517 break outerLoop
1518 }
1519 } else {
1520 logger.Errorw(ctx, "Tp instance is nil", log.Fields{"tp-id": tpID, "tpPath": tpPath,
1521 "uni-id": uniID, "device-id": dh.DeviceID})
1522 techProfInstLoadFailed = true
1523 break outerLoop
1524 }
1525 }
1526 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1527 persMutexLock = true
1528 }
1529 if persMutexLock {
1530 pDevEntry.MutexPersOnuConfig.RUnlock()
1531 }
1532 go dh.deviceRebootStateUpdate(ctx, techProfInstLoadFailed)
1533 return continueWithFlowConfig
1534}
1535
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001538
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001539 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001540 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001541 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001543 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001544 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001545
1546 // deadline context to ensure completion of background routines waited for
1547 //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 +05301548 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301550 defer cancel()
1551 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1552 if err != nil {
1553 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1554 return err
1555 }
1556 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001557}
1558
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301559// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001560// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301561//
1562// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1563//
1564// was and is called in background - error return does not make sense
akashreddyke30dfa92025-11-26 10:51:57 +05301565func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001566 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001567 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
akashreddyke30dfa92025-11-26 10:51:57 +05301569 return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
ozgecanetsiae11479f2020-07-06 09:44:47 +03001570 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301572 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001573 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
akashreddyke30dfa92025-11-26 10:51:57 +05301574 return err
Himani Chawla4d908332020-08-31 12:30:20 +05301575 }
mpagenko01e726e2020-10-23 09:45:29 +00001576
1577 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001578 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001579
mpagenko44bd8362021-11-15 11:40:05 +00001580 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001581 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001582 // 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 +05301583 go func() {
1584 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
1585 DeviceId: dh.DeviceID,
1586 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
1587 OperStatus: voltha.OperStatus_DISCOVERED,
1588 }); err != nil {
1589 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
1590 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
1591 return
1592 }
1593 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
1594 logger.Errorw(ctx, "errror-updating-device-reason-to-core", log.Fields{"device-id": dh.DeviceID, "error": err})
1595 return
1596 }
1597 dh.SetReadyForOmciConfig(false)
1598 }()
1599 return nil
mpagenko8b07c1b2020-11-26 10:36:31 +00001600 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1601 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1602 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1603 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001604}
1605
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301606// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1607//
1608// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001609func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001610 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001611 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001613
1614 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001616 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1618 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001619 }
1620
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001622 var inactiveImageID uint16
1623 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1624 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001625 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1626 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001627 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001629 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001630 if err == nil {
1631 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1632 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001634 }
1635 } else {
1636 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001637 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001638 }
mpagenko15ff4a52021-03-02 10:09:20 +00001639 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001640 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001642 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1643 dh.upgradeCanceled = true
1644 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1645 }
mpagenko38662d02021-08-11 09:45:19 +00001646 //no effort spent anymore for the old API to automatically cancel and restart the download
1647 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001648 }
mpagenko15ff4a52021-03-02 10:09:20 +00001649 } else {
1650 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001652 }
1653 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1655 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001656 }
1657 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001658}
1659
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301660// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001661// after the OnuImage has been downloaded to the adapter, called in background
1662func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001664
1665 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001667 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001669 return
1670 }
1671
1672 var inactiveImageID uint16
1673 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1674 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001676
mpagenko59862f02021-10-11 08:53:18 +00001677 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001679 // but must be still locked at calling createOnuUpgradeFsm
1680 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1681 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1682 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001683 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1684 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001686 //flush the remove upgradeFsmChan channel
1687 select {
1688 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001689 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001690 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001691 }
mpagenko59862f02021-10-11 08:53:18 +00001692 dh.lockUpgradeFsm.Unlock()
1693 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1694 dh.upgradeCanceled = true
1695 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1696 }
mpagenko38662d02021-08-11 09:45:19 +00001697 select {
1698 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001700 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1701 return
1702 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001703 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001704 }
mpagenko59862f02021-10-11 08:53:18 +00001705 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001706 }
mpagenko38662d02021-08-11 09:45:19 +00001707
1708 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001709 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001710 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001711 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001712 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001713 if err == nil {
1714 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1715 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1716 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001718 return
1719 }
mpagenko38662d02021-08-11 09:45:19 +00001720 } else {
1721 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001722 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001723 }
1724 return
1725 }
1726 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001727 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001728}
1729
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301730// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001731func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1732 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001733 var err error
1734 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1735 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1736 // 2.) activation of the inactive image
1737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001738 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001739 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1741 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001742 }
1743 dh.lockUpgradeFsm.RLock()
1744 if dh.pOnuUpradeFsm != nil {
1745 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001746 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001747 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1749 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001750 }
mpagenko59862f02021-10-11 08:53:18 +00001751 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1752 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1753 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1754 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001755 // use the OnuVendor identification from this device for the internal unique name
1756 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001757 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001758 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001759 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001760 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001761 "device-id": dh.DeviceID, "error": err})
1762 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001763 }
mpagenko183647c2021-06-08 15:25:04 +00001764 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001765 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001766 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001767 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001768 } //else
1769 dh.lockUpgradeFsm.RUnlock()
1770
1771 // 2.) check if requested image-version equals the inactive one and start its activation
1772 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1773 var inactiveImageID uint16
1774 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1775 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001776 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1777 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001778 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001779 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001780 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001781 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001782 if err == nil {
1783 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1784 inactiveImageID, aCommitRequest); err != nil {
1785 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001786 "device-id": dh.DeviceID, "error": err})
1787 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001788 }
1789 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001790 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001791 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001792 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001793 } //else
1794 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001795 "device-id": dh.DeviceID, "error": err})
1796 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001797}
1798
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301799// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001800func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1801 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001802 var err error
1803 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1804 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1805 // 2.) commitment of the active image
1806
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001807 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001808 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001809 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1810 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001811 }
1812 dh.lockUpgradeFsm.RLock()
1813 if dh.pOnuUpradeFsm != nil {
1814 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001815 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001816 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001817 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1818 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001819 }
mpagenko59862f02021-10-11 08:53:18 +00001820 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1821 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1822 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1823 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001824 // use the OnuVendor identification from this device for the internal unique name
1825 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001826 // 1.) check a started upgrade process and relay the commitment request to it
1827 // the running upgrade may be based either on the imageIdentifier (started from download)
1828 // or on the imageVersion (started from pure activation)
1829 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1830 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001831 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001832 "device-id": dh.DeviceID, "error": err})
1833 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001834 }
mpagenko183647c2021-06-08 15:25:04 +00001835 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001836 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001837 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001838 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001839 } //else
1840 dh.lockUpgradeFsm.RUnlock()
1841
mpagenko183647c2021-06-08 15:25:04 +00001842 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001843 var activeImageID uint16
1844 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1845 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001846 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1847 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001848 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001849 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001850 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001851 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001852 if err == nil {
1853 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1854 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001855 "device-id": dh.DeviceID, "error": err})
1856 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001857 }
1858 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001859 "device-id": dh.DeviceID, "image-version": aVersion})
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 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001864 "device-id": dh.DeviceID, "error": err})
1865 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001866}
1867
mpagenkoaa3afe92021-05-21 16:20:58 +00001868func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001869 aVersion string) *voltha.ImageState {
1870 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001871 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001872 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001873 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001874 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1875 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1876 if aVersion == dh.pLastUpgradeImageState.Version {
1877 pImageState = dh.pLastUpgradeImageState
1878 } else { //state request for an image version different from last processed image version
1879 pImageState = &voltha.ImageState{
1880 Version: aVersion,
1881 //we cannot state something concerning this version
1882 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1883 Reason: voltha.ImageState_NO_ERROR,
1884 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1885 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001886 }
1887 }
mpagenko38662d02021-08-11 09:45:19 +00001888 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001889}
1890
1891func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1892 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001893 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001894 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001895 dh.lockUpgradeFsm.RLock()
1896 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001897 dh.lockUpgradeFsm.RUnlock()
1898 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001899 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001900 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1901 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1902 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1903 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1904 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1905 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001906 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1907 dh.upgradeCanceled = true
1908 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1909 }
mpagenko45586762021-10-01 08:30:22 +00001910 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001911 } else {
mpagenko45586762021-10-01 08:30:22 +00001912 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001913 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1914 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1915 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1916 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1917 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1918 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001919 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1920 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001921 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1922 //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 +00001923 }
1924}
1925
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001926func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1927
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001928 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001929
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001931 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001932 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1933 pDevEntry.MutexOnuImageStatus.Lock()
1934 pDevEntry.POnuImageStatus = onuImageStatus
1935 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001936
1937 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001939 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1940 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1942 pDevEntry.MutexOnuImageStatus.Lock()
1943 pDevEntry.POnuImageStatus = nil
1944 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001945 return images, err
1946}
1947
Himani Chawla6d2ae152020-09-02 13:11:20 +05301948// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949// #####################################################################################
1950
1951// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301952// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001953
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001955 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1956 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001957}
1958
1959// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001961
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001962 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001963 var err error
1964
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001965 // populate what we know. rest comes later after mib sync
1966 dh.device.Root = false
1967 dh.device.Vendor = "OpenONU"
1968 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001970 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001971
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001973
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 if !dh.IsReconciling() {
1975 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301976 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04001977 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1978 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301979 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001980 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301981 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001983 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001984
Himani Chawla4d908332020-08-31 12:30:20 +05301985 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001986 dh.ponPortNumber = dh.device.ParentPortNo
1987
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001988 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1989 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1990 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001991 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001992 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301993 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001994
1995 /*
1996 self._pon = PonPort.create(self, self._pon_port_number)
1997 self._pon.add_peer(self.parent_id, self._pon_port_number)
1998 self.logger.debug('adding-pon-port-to-agent',
1999 type=self._pon.get_port().type,
2000 admin_state=self._pon.get_port().admin_state,
2001 oper_status=self._pon.get_port().oper_status,
2002 )
2003 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302005 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002006 var ponPortNo uint32 = 1
2007 if dh.ponPortNumber != 0 {
2008 ponPortNo = dh.ponPortNumber
2009 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002011 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002012 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002013 PortNo: ponPortNo,
2014 Label: fmt.Sprintf("pon-%d", ponPortNo),
2015 Type: voltha.Port_PON_ONU,
2016 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05302017 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002018 PortNo: ponPortNo}}, // Peer port is parent's port number
2019 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002020 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002021 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002022 e.Cancel(err)
2023 return
2024 }
2025 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302026 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002027 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002028 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002029}
2030
2031// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002034 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002035 var err error
2036 /*
2037 dh.Client = oop.NewOpenoltClient(dh.clientCon)
2038 dh.pTransitionMap.Handle(ctx, GrpcConnected)
2039 return nil
2040 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002042 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002043 e.Cancel(err)
2044 return
2045 }
2046
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002047 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002049 // reconcilement will be continued after mib download is done
2050 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08002051
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002052 /*
2053 ############################################################################
2054 # Setup Alarm handler
2055 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
2056 device.serial_number)
2057 ############################################################################
2058 # Setup PM configuration for this device
2059 # Pass in ONU specific options
2060 kwargs = {
2061 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
2062 'heartbeat': self.heartbeat,
2063 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
2064 }
2065 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
2066 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
2067 self.logical_device_id, device.serial_number,
2068 grouped=True, freq_override=False, **kwargs)
2069 pm_config = self._pm_metrics.make_proto()
2070 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
2071 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
2072 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
2073
2074 # Note, ONU ID and UNI intf set in add_uni_port method
2075 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
2076 ani_ports=[self._pon])
2077
2078 # Code to Run OMCI Test Action
2079 kwargs_omci_test_action = {
2080 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2081 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2082 }
2083 serial_number = device.serial_number
2084 self._test_request = OmciTestRequest(self.core_proxy,
2085 self.omci_agent, self.device_id,
2086 AniG, serial_number,
2087 self.logical_device_id,
2088 exclusive=False,
2089 **kwargs_omci_test_action)
2090
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002092 else:
2093 self.logger.info('onu-already-activated')
2094 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08002095
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002096 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002097}
2098
2099// doStateConnected get the device info and update to voltha core
2100// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302101//
2102// voltha-openolt-adapter/adaptercore/device_handler.go
2103// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002105
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002106 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302107 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002108 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002109 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002110}
2111
2112// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00002113func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002114
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002115 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302116 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002117 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002118 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002119
2120 /*
2121 // Synchronous call to update device state - this method is run in its own go routine
2122 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
2123 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002124 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 +00002125 return err
2126 }
2127 return nil
2128 */
2129}
2130
2131// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002133
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002134 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002135 var err error
2136
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002137 device := dh.device
2138 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002139 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002141 e.Cancel(err)
2142 return
2143 }
2144
2145 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002147 /*
2148 // Update the all ports state on that device to disable
2149 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002150 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002151 return er
2152 }
2153
2154 //Update the device oper state and connection status
2155 cloned.OperStatus = voltha.OperStatus_UNKNOWN
2156 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
2157 dh.device = cloned
2158
2159 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002160 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002161 return er
2162 }
2163
2164 //get the child device for the parent device
2165 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
2166 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00002167 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002168 return err
2169 }
2170 for _, onuDevice := range onuDevices.Items {
2171
2172 // Update onu state as down in onu adapter
2173 onuInd := oop.OnuIndication{}
2174 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04002175 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002176 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
2177 if er != nil {
2178 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00002179 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002180 //Do not return here and continue to process other ONUs
2181 }
2182 }
2183 // * Discovered ONUs entries need to be cleared , since after OLT
2184 // is up, it starts sending discovery indications again* /
2185 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00002186 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002187 return nil
2188 */
Himani Chawla4d908332020-08-31 12:30:20 +05302189 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002190 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002191 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002192}
2193
Himani Chawla6d2ae152020-09-02 13:11:20 +05302194// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002195// #################################################################################
2196
2197// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05302198// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002199
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302200// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002201func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00002202 dh.lockDevice.RLock()
2203 pOnuDeviceEntry := dh.pOnuOmciDevice
2204 if aWait && pOnuDeviceEntry == nil {
2205 //keep the read sema short to allow for subsequent write
2206 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002208 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
2209 // so it might be needed to wait here for that event with some timeout
2210 select {
2211 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002213 return nil
2214 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002216 // if written now, we can return the written value without sema
2217 return dh.pOnuOmciDevice
2218 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002219 }
mpagenko3af1f032020-06-10 08:53:41 +00002220 dh.lockDevice.RUnlock()
2221 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002222}
2223
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302224// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
2226 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002227 dh.lockDevice.Lock()
2228 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00002229 dh.pOnuOmciDevice = apDeviceEntry
2230 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08002231 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05302232 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07002233 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002234}
2235
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302236// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302237//
2238//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05302239func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002240 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002241
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002243 if deviceEntry == nil {
2244 /* costum_me_map in python code seems always to be None,
2245 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
2246 /* also no 'clock' argument - usage open ...*/
2247 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
2249 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
2250 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
2251 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
2252 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002253 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00002255 // fire deviceEntry ready event to spread to possibly waiting processing
2256 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002258 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002259 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002260 }
2261 // might be updated with some error handling !!!
2262 return nil
2263}
2264
dbainbri4d3a0dc2020-12-02 00:33:42 +00002265func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002266 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002267 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
2268
2269 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002270
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002272 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2274 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002275 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302276
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002279 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002280
khenaidoo42dcdfd2021-10-19 17:34:12 -04002281 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002282 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002283 OperStatus: voltha.OperStatus_ACTIVATING,
2284 ConnStatus: voltha.ConnectStatus_REACHABLE,
2285 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002286 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002287 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302288 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
2289 }
2290 // On onu reboot, we have to perform mib-reset and persist the reboot state for reconciling scenario
2291 if dh.GetDeviceTechProfOnReboot() {
2292 pDevEntry.MutexPersOnuConfig.Lock()
2293 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2294 pDevEntry.SOnuPersistentData.PersRebootInProgress = true
2295 pDevEntry.MutexPersOnuConfig.Unlock()
2296 }
2297 // Moving the previous call to write to KV store here, to store the ONU pers data after the update.
2298 if err := dh.StorePersistentData(ctx); err != nil {
2299 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2300 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002301 }
2302 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302303 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002305
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002306 pDevEntry.MutexPersOnuConfig.RLock()
2307 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2308 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002309 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 +00002310 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002311 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302312
2313 //VOL-4965: Recover previously Activating ONU during reconciliation.
2314 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2315 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2316 log.Fields{"device-id": dh.DeviceID})
2317 pDevEntry.MutexPersOnuConfig.Lock()
2318 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2319 pDevEntry.MutexPersOnuConfig.Unlock()
2320 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002321 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002323 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002324 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002325 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2326 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2327 // 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 +00002328 // 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 +00002329 // so let's just try to keep it simple ...
2330 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002332 if err != nil || device == nil {
2333 //TODO: needs to handle error scenarios
2334 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2335 return errors.New("Voltha Device not found")
2336 }
2337 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002338
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002340 return err
mpagenko3af1f032020-06-10 08:53:41 +00002341 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002342 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302343 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2344 /* this might be a good time for Omci Verify message? */
2345 verifyExec := make(chan bool)
2346 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2347 dh.device.Id, pDevEntry.PDevOmciCC, false,
2348 true, true) //exclusive and allowFailure (anyway not yet checked)
2349 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002350
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302351 /* give the handler some time here to wait for the OMCi verification result
2352 after Timeout start and try MibUpload FSM anyway
2353 (to prevent stopping on just not supported OMCI verification from ONU) */
2354 select {
2355 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2356 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2357 case testresult := <-verifyExec:
2358 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2359 case <-dh.deviceDeleteCommChan:
2360 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2361 return nil
2362 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002363 }
2364
2365 /* In py code it looks earlier (on activate ..)
2366 # Code to Run OMCI Test Action
2367 kwargs_omci_test_action = {
2368 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2369 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2370 }
2371 serial_number = device.serial_number
2372 self._test_request = OmciTestRequest(self.core_proxy,
2373 self.omci_agent, self.device_id,
2374 AniG, serial_number,
2375 self.logical_device_id,
2376 exclusive=False,
2377 **kwargs_omci_test_action)
2378 ...
2379 # Start test requests after a brief pause
2380 if not self._test_request_started:
2381 self._test_request_started = True
2382 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2383 reactor.callLater(tststart, self._test_request.start_collector)
2384
2385 */
2386 /* which is then: in omci_test_request.py : */
2387 /*
2388 def start_collector(self, callback=None):
2389 """
2390 Start the collection loop for an adapter if the frequency > 0
2391
2392 :param callback: (callable) Function to call to collect PM data
2393 """
2394 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2395 if callback is None:
2396 callback = self.perform_test_omci
2397
2398 if self.lc is None:
2399 self.lc = LoopingCall(callback)
2400
2401 if self.default_freq > 0:
2402 self.lc.start(interval=self.default_freq / 10)
2403
2404 def perform_test_omci(self):
2405 """
2406 Perform the initial test request
2407 """
2408 ani_g_entities = self._device.configuration.ani_g_entities
2409 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2410 is not None else None
2411 self._entity_id = ani_g_entities_ids[0]
2412 self.logger.info('perform-test', entity_class=self._entity_class,
2413 entity_id=self._entity_id)
2414 try:
2415 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2416 result = yield self._device.omci_cc.send(frame)
2417 if not result.fields['omci_message'].fields['success_code']:
2418 self.logger.info('Self-Test Submitted Successfully',
2419 code=result.fields[
2420 'omci_message'].fields['success_code'])
2421 else:
2422 raise TestFailure('Test Failure: {}'.format(
2423 result.fields['omci_message'].fields['success_code']))
2424 except TimeoutError as e:
2425 self.deferred.errback(failure.Failure(e))
2426
2427 except Exception as e:
2428 self.logger.exception('perform-test-Error', e=e,
2429 class_id=self._entity_class,
2430 entity_id=self._entity_id)
2431 self.deferred.errback(failure.Failure(e))
2432
2433 */
2434
2435 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002436 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002437
mpagenko1cc3cb42020-07-27 15:24:38 +00002438 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2439 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2440 * 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 +05302441 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002442 */
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302443
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002444 //call MibUploadFSM - transition up to state UlStInSync
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302445 // Breaking this part of code due to sca complexity
2446 err := dh.CheckAndStartMibUploadFsm(ctx, pDevEntry)
2447 return err
2448}
2449
2450func (dh *deviceHandler) CheckAndStartMibUploadFsm(ctx context.Context, pDevEntry *mib.OnuDeviceEntry) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002451 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002452 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 if pMibUlFsm.Is(mib.UlStDisabled) {
2454 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2455 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2456 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302457 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002458 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302459 //Determine ONU status and start/re-start MIB Synchronization tasks
2460 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 if pDevEntry.IsNewOnu() {
2462 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2463 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2464 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002465 }
Himani Chawla4d908332020-08-31 12:30:20 +05302466 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002467 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2468 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2469 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302470 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002471 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002472 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002473 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002474 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 "device-id": dh.DeviceID})
2476 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002477 }
2478 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002479 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2480 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002481 }
2482 return nil
2483}
2484
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002485func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002486 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002487 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002488 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302489 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002490
mpagenko900ee4b2020-10-12 11:56:34 +00002491 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2492 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2493 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002494 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002497 // abort: system behavior is just unstable ...
2498 return err
2499 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002500 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302501 if !dh.GetDeviceTechProfOnReboot() {
2502 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
2503 }
mpagenko900ee4b2020-10-12 11:56:34 +00002504
2505 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002506 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002508 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2510 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002511 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002513
2514 //TODO!!! remove existing traffic profiles
2515 /* from py code, if TP's exist, remove them - not yet implemented
2516 self._tp = dict()
2517 # Let TP download happen again
2518 for uni_id in self._tp_service_specific_task:
2519 self._tp_service_specific_task[uni_id].clear()
2520 for uni_id in self._tech_profile_download_done:
2521 self._tech_profile_download_done[uni_id].clear()
2522 */
2523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002525
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002526 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002527
mpagenkoe4782082021-11-25 12:04:26 +00002528 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002529 // abort: system behavior is just unstable ...
2530 return err
2531 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002532 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002534 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002535 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002536 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2537 OperStatus: voltha.OperStatus_DISCOVERED,
2538 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002539 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002542 // abort: system behavior is just unstable ...
2543 return err
2544 }
2545 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002546 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002547 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002548 return nil
2549}
2550
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002551func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002552 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2553 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2554 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2555 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002556 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002557
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302559 //VOL-5260: During race conditions when adoptDevice has not yet completed
2560 // and deleteDevice is issued , returning error will further prevent clean up
2561 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002562 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302563 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2564 logger.Error(ctx, errMsg)
2565 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002566 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002567 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002568 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002569 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 pDevEntry.MutexOnuImageStatus.RLock()
2571 if pDevEntry.POnuImageStatus != nil {
2572 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002573 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002575
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002576 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002577 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002578 }
2579 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002581 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002583 }
mpagenko101ac942021-11-16 15:01:29 +00002584 //stop any deviceHandler reconcile processing (if running)
2585 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002586 //port lock/unlock FSM's may be active
2587 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002589 }
2590 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002592 }
2593 //techProfile related PonAniConfigFsm FSM may be active
2594 if dh.pOnuTP != nil {
2595 // should always be the case here
2596 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 if dh.pOnuTP.PAniConfigFsm != nil {
2598 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2599 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002600 }
mpagenko900ee4b2020-10-12 11:56:34 +00002601 }
2602 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002603 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002604 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002606 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002607 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002608 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002609 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002610 } else {
2611 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002612 }
2613 }
2614 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302615
2616 dh.mutexCollectorFlag.Lock()
2617 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2618 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002619 // Stop collector routine
2620 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302621 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002622 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302623 dh.mutexCollectorFlag.Unlock()
2624
2625 dh.mutextAlarmManagerFlag.Lock()
2626 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2627 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302628 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302629 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302630 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302631 dh.mutextAlarmManagerFlag.Unlock()
2632
2633 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2634 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2635 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302637 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002638 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302639 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302640
Girish Gowdrae95687a2021-09-08 16:30:58 -07002641 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2642
mpagenko80622a52021-02-09 16:53:23 +00002643 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002645 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002646 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002647 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002648 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002649 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002650 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2651 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2652 // (even though it may also run into direct cancellation, a bit hard to verify here)
2653 // so don't set 'dh.upgradeCanceled = true' here!
2654 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2655 }
mpagenko38662d02021-08-11 09:45:19 +00002656 }
mpagenko80622a52021-02-09 16:53:23 +00002657
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002659 return nil
2660}
2661
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302662//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2664 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 +05302665
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002666 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002668 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002670 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002671 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002672 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002673
mpagenkoa40e99a2020-11-17 13:50:39 +00002674 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2675 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2676 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2677 * disable/enable toggling here to allow traffic
2678 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2679 * like the py comment says:
2680 * # start by locking all the unis till mib sync and initial mib is downloaded
2681 * # this way we can capture the port down/up events when we are ready
2682 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302683
mpagenkoa40e99a2020-11-17 13:50:39 +00002684 // Init Uni Ports to Admin locked state
2685 // *** should generate UniLockStateDone event *****
2686 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002688 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002690 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002691 }
2692}
2693
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302694//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2696 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302697 /* Mib download procedure -
2698 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2699 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002700 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002701 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002703 return
2704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302706 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 if pMibDlFsm.Is(mib.DlStDisabled) {
2708 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2709 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 +05302710 // maybe try a FSM reset and then again ... - TODO!!!
2711 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002712 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302713 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2715 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302716 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002717 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302718 //Begin MIB data download (running autonomously)
2719 }
2720 }
2721 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002722 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302724 // maybe try a FSM reset and then again ... - TODO!!!
2725 }
2726 /***** Mib download started */
2727 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302729 }
2730}
2731
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302732//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302734 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002735 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2736 if pDevEntry == nil {
2737 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2738 return
2739 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002741 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002743 // update device info in core
2744 pDevEntry.MutexPersOnuConfig.RLock()
2745 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2746 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2747 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2748 pDevEntry.MutexPersOnuConfig.RUnlock()
2749 dh.logicalDeviceID = dh.DeviceID
2750 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2751 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2752 }
2753 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002754 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2755 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2756 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2757 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002758 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002760 ConnStatus: voltha.ConnectStatus_REACHABLE,
2761 OperStatus: voltha.OperStatus_ACTIVE,
2762 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302763 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302765 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302767 }
2768 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302769 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302771 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002772 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002773
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002775 var waitForOmciProcessor sync.WaitGroup
2776 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002777 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002778 go dh.StartCollector(ctx, &waitForOmciProcessor)
2779 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002780 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 if !dh.GetAlarmManagerIsRunning(ctx) {
2782 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002783 }
2784
Girish Gowdrae95687a2021-09-08 16:30:58 -07002785 // Start flow handler routines per UNI
2786 for _, uniPort := range dh.uniEntityMap {
2787 // only if this port was enabled for use by the operator at startup
2788 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2789 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2790 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2791 }
2792 }
2793 }
2794
Girish Gowdrae0140f02021-02-02 16:55:09 -08002795 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002796 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002797 // There is no way we should be landing here, but if we do then
2798 // there is nothing much we can do about this other than log error
2799 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2800 }
2801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002803
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002804 pDevEntry.MutexPersOnuConfig.RLock()
2805 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2806 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302807 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002809 dh.mutexForDisableDeviceRequested.Lock()
2810 dh.disableDeviceRequested = true
2811 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002812 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002813 // reconcilement will be continued after ani config is done
2814 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002816 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002817 dh.mutexForDisableDeviceRequested.RLock()
2818 if !dh.disableDeviceRequested {
2819 if dh.pUnlockStateFsm == nil {
2820 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2821 } else { //UnlockStateFSM already init
2822 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2823 dh.runUniLockFsm(ctx, false)
2824 }
2825 dh.mutexForDisableDeviceRequested.RUnlock()
2826 } else {
2827 dh.mutexForDisableDeviceRequested.RUnlock()
2828 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002829 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302830 }
2831}
2832
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302833//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2835 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302836
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002837 if !dh.IsReconciling() {
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05302838 // Check if TPs are available post device reboot. If TPs are available start processing them and configure flows
2839 if dh.GetDeviceTechProfOnReboot() {
2840 if dh.CheckForDeviceTechProf(ctx) {
2841 go dh.DeviceFlowConfigOnReboot(ctx)
2842 }
2843 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002845 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2847 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002848 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002849 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002850 return
2851 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002852 pDevEntry.MutexPersOnuConfig.Lock()
2853 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2854 pDevEntry.MutexPersOnuConfig.Unlock()
2855 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002856 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002857 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002858 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302859 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302860 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 +00002861 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002862 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302863
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002864 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302865
Himani Chawla26e555c2020-08-31 12:30:20 +05302866 }
2867}
2868
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302869//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002870func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002871 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002872 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002873
mpagenko44bd8362021-11-15 11:40:05 +00002874 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002875 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002877 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002878 OperStatus: voltha.OperStatus_UNKNOWN,
2879 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002880 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002881 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002882 }
2883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002885 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002886 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002887
2888 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002889 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002890
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002891 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002892 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002893 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002894 return
2895 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002896 pDevEntry.MutexPersOnuConfig.Lock()
2897 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2898 pDevEntry.MutexPersOnuConfig.Unlock()
2899 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002901 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002902 }
mpagenko900ee4b2020-10-12 11:56:34 +00002903}
2904
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302905//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002906func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002909 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002911 ConnStatus: voltha.ConnectStatus_REACHABLE,
2912 OperStatus: voltha.OperStatus_ACTIVE,
2913 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002914 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002916 }
2917
dbainbri4d3a0dc2020-12-02 00:33:42 +00002918 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002920 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002921 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002922
2923 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002926 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002927 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002929 return
2930 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 pDevEntry.MutexPersOnuConfig.Lock()
2932 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2933 pDevEntry.MutexPersOnuConfig.Unlock()
2934 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002935 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002937 }
mpagenko900ee4b2020-10-12 11:56:34 +00002938}
2939
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302940//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002941func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2942 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2943 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002944 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002945 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002946 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002947 OperStatus: voltha.OperStatus_FAILED,
2948 }); err != nil {
2949 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2950 }
2951}
2952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2954 if devEvent == cmn.OmciAniConfigDone {
2955 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002956 // attention: the device reason update is done based on ONU-UNI-Port related activity
2957 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002959 // 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 +00002960 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302961 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002962 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002963 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2964 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2965 dh.mutexReconcilingFirstPassFlag.Lock()
2966 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302967 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002968 dh.reconcilingFirstPass = false
2969 go dh.ReconcileDeviceFlowConfig(ctx)
2970 }
2971 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002972 }
2973 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002974 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002975 // attention: the device reason update is done based on ONU-UNI-Port related activity
2976 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002978 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2979 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002980 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002981 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302982}
2983
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002985 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302987 // attention: the device reason update is done based on ONU-UNI-Port related activity
2988 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302989
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2991 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002992 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002993 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002994 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002995 }
2996 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002997 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002998 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002999 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003000 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303001 }
mpagenkof1fc3862021-02-16 10:09:52 +00003002
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00003004 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003006 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00003008 }
3009 } else {
3010 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003012 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303013}
3014
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303015// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05303017 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003018 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003019 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003020 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003021 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00003023 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003024 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00003025 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003026 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003027 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003028 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003029 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003031 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003032 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003033 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003035 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003036 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003037 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07003038 case cmn.UniEnableStateFailed:
3039 {
3040 dh.processUniEnableStateFailedEvent(ctx, devEvent)
3041 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00003043 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003044 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00003045 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00003047 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003048 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00003049 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00003051 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003052 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00003053 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003054 default:
3055 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003057 }
3058 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003059}
3060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003062 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07003063 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05303064 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003065 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003066 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003067 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05303068 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003070 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003071 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 +00003072 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003073 //store UniPort with the System-PortNumber key
3074 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003076 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003077 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003078 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003079 } //error logging already within UniPort method
3080 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303081 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003082 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003083 }
3084 }
3085}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003087func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
3088 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003089 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003090 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003091 return
3092 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003093 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003095 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
3096 for _, mgmtEntityID := range pptpInstKeys {
3097 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003099 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
3100 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003101 }
3102 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003103 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003104 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003105 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003106 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
3107 for _, mgmtEntityID := range veipInstKeys {
3108 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003109 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003110 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
3111 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003112 }
3113 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003115 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003116 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03003117 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
3118 for _, mgmtEntityID := range potsInstKeys {
3119 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003121 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
3122 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03003123 }
3124 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03003126 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07003127 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003129 return
3130 }
3131
mpagenko2c3f6c52021-11-23 11:22:10 +00003132 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
3133 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
3134 // 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 -07003135 dh.flowCbChan = make([]chan FlowCb, uniCnt)
3136 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
3137 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00003138 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
3139 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303140 dh.chUniVlanConfigOnRebootDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003141 for i := 0; i < int(uniCnt); i++ {
3142 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00003143 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003144 }
3145}
3146
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
3148func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003149 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05303150 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003151 // with following remark:
3152 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
3153 // # load on the core
3154
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003155 // 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 +00003156
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003157 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00003158 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003159 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3160 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303161 uniPort.SetOperState(common.OperStatus_ACTIVE)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003163 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003164 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003165 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003166 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003167 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168 PortNo: port.PortNo,
3169 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003170 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 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 -04003172 }
3173 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003174 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303175 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00003176 }
mpagenko3af1f032020-06-10 08:53:41 +00003177 }
3178 }
3179}
3180
3181// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003182func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
3183 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00003184 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
3185 for uniNo, uniPort := range dh.uniEntityMap {
3186 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02003187
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003188 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
3189 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
mgoudad611f4c2025-10-30 14:49:27 +05303190 uniPort.SetOperState(common.OperStatus_UNKNOWN)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003191 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003192 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003193 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04003194 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003196 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 PortNo: port.PortNo,
3198 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04003199 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200 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 -04003201 }
3202 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003203 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303204 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003205 }
3206
Holger Hildebrandtbe674422020-05-05 13:05:30 +00003207 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003208 }
3209}
3210
3211// ONU_Active/Inactive announcement on system KAFKA bus
3212// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
mgoudad611f4c2025-10-30 14:49:27 +05303213func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState common.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003214 var de voltha.DeviceEvent
3215 eventContext := make(map[string]string)
3216 //Populating event context
3217 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04003218 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003219 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003220 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003221 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00003222 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 +00003223 }
3224 oltSerialNumber := parentDevice.SerialNumber
3225
3226 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
3227 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
3228 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05303229 eventContext["olt-serial-number"] = oltSerialNumber
3230 eventContext["device-id"] = aDeviceID
3231 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003232 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003233 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
3234 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00003235 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
3236 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
3238 deviceEntry.MutexPersOnuConfig.RUnlock()
3239 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003240 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03003241 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
3242 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
3243 } else {
3244 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
3245 log.Fields{"device-id": aDeviceID})
3246 return
3247 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003248
3249 /* Populating device event body */
3250 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05303251 de.ResourceId = aDeviceID
3252 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003253 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
3254 de.Description = fmt.Sprintf("%s Event - %s - %s",
3255 cEventObjectType, cOnuActivatedEvent, "Raised")
3256 } else {
3257 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
3258 de.Description = fmt.Sprintf("%s Event - %s - %s",
3259 cEventObjectType, cOnuActivatedEvent, "Cleared")
3260 }
3261 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05303262 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003263 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05303264 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003265 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303266 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05303267 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003268}
3269
Himani Chawla4d908332020-08-31 12:30:20 +05303270// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303272 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003273 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05303274 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003275 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003276 sFsmName = "LockStateFSM"
3277 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003278 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003279 sFsmName = "UnLockStateFSM"
3280 }
mpagenko3af1f032020-06-10 08:53:41 +00003281
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003282 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00003283 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00003285 return
3286 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003287 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003288 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05303289 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003290 dh.pLockStateFsm = pLSFsm
3291 } else {
3292 dh.pUnlockStateFsm = pLSFsm
3293 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003294 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003295 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003296 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003297 }
3298}
3299
3300// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00003301func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003302 /* Uni Port lock/unlock procedure -
3303 ***** should run via 'adminDone' state and generate the argument requested event *****
3304 */
3305 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05303306 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003307 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003308 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3309 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003310 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3311 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003312 }
3313 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003314 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003315 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
3316 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003317 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
3318 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003319 }
3320 }
3321 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003322 if pLSStatemachine.Is(uniprt.UniStDisabled) {
3323 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003324 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003325 // maybe try a FSM reset and then again ... - TODO!!!
3326 } else {
3327 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003328 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003329 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003330 }
3331 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003332 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003334 // maybe try a FSM reset and then again ... - TODO!!!
3335 }
3336 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003337 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003338 // maybe try a FSM reset and then again ... - TODO!!!
3339 }
3340}
3341
mpagenko80622a52021-02-09 16:53:23 +00003342// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003343// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303344//
3345//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003346func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303347 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003348 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003350 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303352 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003353 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003354 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003355 sFsmName, chUpgradeFsm)
3356 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003357 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003358 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3360 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003361 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003362 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303363 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003364 }
mpagenko59862f02021-10-11 08:53:18 +00003365 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003366 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3367 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003368 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3369 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003370 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003371 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003372 } else {
3373 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003375 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303376 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003377 }
3378 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003380 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303381 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003382 }
3383 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303385 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003386 }
3387 return nil
3388}
3389
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3391func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003392 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003393 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003394 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003395 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3396 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003397 dh.pLastUpgradeImageState = apImageState
3398 dh.lockUpgradeFsm.Unlock()
3399 //signal upgradeFsm removed using non-blocking channel send
3400 select {
3401 case dh.upgradeFsmChan <- struct{}{}:
3402 default:
3403 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003405 }
mpagenko80622a52021-02-09 16:53:23 +00003406}
3407
mpagenko15ff4a52021-03-02 10:09:20 +00003408// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3409func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003410 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003411 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003413 return
3414 }
3415
3416 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003417 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003418 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003419 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3420 dh.lockUpgradeFsm.RUnlock()
3421 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3422 return
3423 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003425 if pUpgradeStatemachine != nil {
3426 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3427 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003428 UpgradeState := pUpgradeStatemachine.Current()
3429 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3430 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3431 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003432 // 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 +00003433 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003434 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3435 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003436 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003437 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003439 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3440 dh.upgradeCanceled = true
3441 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3442 }
mpagenko15ff4a52021-03-02 10:09:20 +00003443 return
3444 }
mpagenko59862f02021-10-11 08:53:18 +00003445 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3447 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003448 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003449 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003450 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3451 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003452 return
3453 }
3454 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003456 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003457 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3458 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003459 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3460 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003461 return
3462 }
3463 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003464 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003465 }
3466 } else {
3467 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 +00003468 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003469 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3470 dh.upgradeCanceled = true
3471 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3472 }
mpagenko1f8e8822021-06-25 14:10:21 +00003473 }
mpagenko15ff4a52021-03-02 10:09:20 +00003474 return
3475 }
mpagenko59862f02021-10-11 08:53:18 +00003476 dh.lockUpgradeFsm.RUnlock()
3477 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3478 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003479 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3480 dh.upgradeCanceled = true
3481 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3482 }
mpagenko59862f02021-10-11 08:53:18 +00003483 return
3484 }
3485 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3486 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3487 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3488 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3489 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3490 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3491 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003492 }
mpagenko15ff4a52021-03-02 10:09:20 +00003493 }
3494 }
3495 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003496 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003497 }
mpagenko59862f02021-10-11 08:53:18 +00003498 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003499}
3500
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303501// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003503
3504 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003505 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003506 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003507 kvbackend := &db.Backend{
3508 Client: dh.pOpenOnuAc.kvClient,
3509 StoreType: dh.pOpenOnuAc.KVStoreType,
3510 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003511 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003512 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3513 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003514
mpagenkoaf801632020-07-03 10:00:42 +00003515 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003516}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303517
3518//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003519func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303520 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003521
mpagenkodff5dda2020-08-28 11:52:01 +00003522 for _, field := range flow.GetOfbFields(apFlowItem) {
3523 switch field.Type {
3524 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3525 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003527 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3528 }
mpagenko01e726e2020-10-23 09:45:29 +00003529 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003530 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3531 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303532 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303534 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3535 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003536 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3537 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003538 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303540 return
mpagenkodff5dda2020-08-28 11:52:01 +00003541 }
3542 }
mpagenko01e726e2020-10-23 09:45:29 +00003543 */
mpagenkodff5dda2020-08-28 11:52:01 +00003544 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3545 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303546 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003547 loMatchVlanMask := uint16(field.GetVlanVidMask())
mgoudad611f4c2025-10-30 14:49:27 +05303548 if *loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) ||
3549 loMatchVlanMask != uint16(of.OfpVlanId_OFPVID_PRESENT) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303550 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003551 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303553 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003554 }
3555 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3556 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303557 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003558 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303559 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003560 }
3561 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3562 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003563 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003564 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3565 }
3566 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3567 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003568 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003569 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3570 }
3571 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3572 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003574 "IPv4-DST": field.GetIpv4Dst()})
3575 }
3576 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3577 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003579 "IPv4-SRC": field.GetIpv4Src()})
3580 }
3581 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3582 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003584 "Metadata": field.GetTableMetadata()})
3585 }
3586 /*
3587 default:
3588 {
3589 //all other entires ignored
3590 }
3591 */
3592 }
3593 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303594}
mpagenkodff5dda2020-08-28 11:52:01 +00003595
khenaidoo7d3c5582021-08-11 18:09:44 -04003596func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003597 for _, action := range flow.GetActions(apFlowItem) {
3598 switch action.Type {
3599 /* not used:
3600 case of.OfpActionType_OFPAT_OUTPUT:
3601 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003602 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003603 "Output": action.GetOutput()})
3604 }
3605 */
3606 case of.OfpActionType_OFPAT_PUSH_VLAN:
3607 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003608 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003609 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3610 }
3611 case of.OfpActionType_OFPAT_SET_FIELD:
3612 {
3613 pActionSetField := action.GetSetField()
3614 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003615 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003616 "OxcmClass": pActionSetField.Field.OxmClass})
3617 }
3618 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303619 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003620 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303621 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003622 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303623 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003624 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303625 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003626 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003627 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003628 "Type": pActionSetField.Field.GetOfbField().Type})
3629 }
3630 }
3631 /*
3632 default:
3633 {
3634 //all other entires ignored
3635 }
3636 */
3637 }
3638 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303639}
3640
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303641// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003642func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003643 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
mgoudad611f4c2025-10-30 14:49:27 +05303644 var loSetVlan = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3645 var loMatchVlan = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303646 var loSetPcp uint8
3647 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303648 var loIPProto uint32
3649 /* the TechProfileId is part of the flow Metadata - compare also comment within
3650 * OLT-Adapter:openolt_flowmgr.go
3651 * Metadata 8 bytes:
3652 * Most Significant 2 Bytes = Inner VLAN
3653 * Next 2 Bytes = Tech Profile ID(TPID)
3654 * Least Significant 4 Bytes = Port ID
3655 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3656 * subscriber related flows.
3657 */
3658
dbainbri4d3a0dc2020-12-02 00:33:42 +00003659 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303660 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003661 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003663 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303664 }
mpagenko551a4d42020-12-08 18:09:20 +00003665 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003666 loCookie := apFlowItem.GetCookie()
3667 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303668 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003669 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303670 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303671
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303672 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003673 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303674 if loIPProto == 2 {
3675 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3676 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003677 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003678 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303679 return nil
3680 }
mpagenko01e726e2020-10-23 09:45:29 +00003681 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003682 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003683
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303684 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3685 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003686 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003687 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003688 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3689 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3690 //TODO!!: Use DeviceId within the error response to rwCore
3691 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003692 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003693 }
3694 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003696 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303697 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3698 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3699 loSetVlan = loMatchVlan
3700 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 +00003701 } else {
3702 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3703 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3704 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303705 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003706 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003707 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003708 }
mpagenko9a304ea2020-12-16 15:54:01 +00003709
khenaidoo42dcdfd2021-10-19 17:34:12 -04003710 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003711 if apFlowMetaData != nil {
3712 meter = apFlowMetaData.Meters[0]
3713 }
mpagenkobc4170a2021-08-17 16:42:10 +00003714 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3715 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3716 // when different rules are requested concurrently for the same uni
3717 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3718 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3719 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3721 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003722 //SetUniFlowParams() may block on some rule that is suspended-to-add
3723 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003724 // Also the error is returned to caller via response channel
3725 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303726 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003727 dh.lockVlanConfig.RUnlock()
3728 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003729 return
mpagenkodff5dda2020-08-28 11:52:01 +00003730 }
mpagenkobc4170a2021-08-17 16:42:10 +00003731 dh.lockVlanConfig.RUnlock()
3732 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003733 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303734 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003735 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003736 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003737 if err != nil {
3738 *respChan <- err
3739 }
mpagenko01e726e2020-10-23 09:45:29 +00003740}
3741
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303742// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003743func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003744 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3745 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3746 //no extra check is done on the rule parameters
3747 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3748 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3749 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3750 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003751 // - 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 +00003752 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003753 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003754
3755 /* TT related temporary workaround - should not be needed anymore
3756 for _, field := range flow.GetOfbFields(apFlowItem) {
3757 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3758 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003760 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3761 if loIPProto == 2 {
3762 // 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 +00003763 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003764 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003765 return nil
3766 }
3767 }
3768 } //for all OfbFields
3769 */
3770
mpagenko9a304ea2020-12-16 15:54:01 +00003771 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003772 dh.lockVlanConfig.RLock()
3773 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003774 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3775 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003776 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3777 return
mpagenko01e726e2020-10-23 09:45:29 +00003778 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003779 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003780 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003781 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003782 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003783 // Push response on the response channel
3784 if respChan != nil {
3785 // 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
3786 select {
3787 case *respChan <- nil:
3788 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3789 default:
3790 }
3791 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003792 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003793}
3794
Himani Chawla26e555c2020-08-31 12:30:20 +05303795// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003796// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003797// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303799 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 +05303800 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003803 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3805 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003806 }
3807
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303808 if dh.pDeviceStateFsm.Current() == devStDown {
3809 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3810 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3811 }
3812
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003813 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3814 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05303815 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, lastFlowToConfOnReboot, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003816 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003817 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3818 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003819 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3820 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003821 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003822 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3823 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003824 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3825 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003826 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003827 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303828 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003829 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3831 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003832 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003833 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003834 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3835 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003836 }
3837 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003838 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 "device-id": dh.DeviceID})
3840 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003841 }
3842 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003843 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003844 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3845 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003846 }
3847 return nil
3848}
3849
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303850// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003851// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003852func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003853 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003854 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003855 for _, uniPort := range dh.uniEntityMap {
3856 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003858 pCurrentUniPort = uniPort
3859 break //found - end search loop
3860 }
3861 }
3862 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003863 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003864 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003865 return
3866 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003867 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003868}
3869
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303870// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003872 //TODO!! verify and start pending flow configuration
3873 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3874 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303875 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003876 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003877 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003878 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003879 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003880 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003881 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003882 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003883 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003884 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3885 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003886 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003887 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003888 } else {
3889 /***** UniVlanConfigFsm continued */
3890 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003891 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3892 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003893 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3895 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003896 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003898 } else {
3899 /***** UniVlanConfigFsm continued */
3900 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003901 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3902 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003903 }
mpagenkodff5dda2020-08-28 11:52:01 +00003904 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003905 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003906 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3907 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003908 }
3909 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003910 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 +00003911 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3912 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003913 }
3914 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003915 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003916 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003917 }
mpagenkof1fc3862021-02-16 10:09:52 +00003918 } else {
3919 dh.lockVlanConfig.RUnlock()
3920 }
mpagenkodff5dda2020-08-28 11:52:01 +00003921}
3922
Akash Soni3de0e062024-12-11 16:37:26 +05303923// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3924func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3925 dh.lockVlanConfig.Lock()
3926 defer dh.lockVlanConfig.Unlock()
3927
3928 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3929 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3930 if pVlanFilterStatemachine != nil {
3931 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3932 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3933 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3934 })
3935 } else {
3936 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3937 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3938 })
3939 }
3940 } else {
3941 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3942 "device-id": dh.DeviceID, "UniPort": uniID,
3943 })
3944 }
3945 } else {
3946 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3947 "device-id": dh.DeviceID, "UniPort": uniID,
3948 })
3949 }
3950}
3951
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303952// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003953// 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 +00003954func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003955 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003957 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003958 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003959 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003960 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003961}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003962
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303963// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003964func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003965 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3966 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3967 // obviously then parallel processing on the cancel must be avoided
3968 // deadline context to ensure completion of background routines waited for
3969 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3970 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3971 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303972 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003973
Akash Soni840f8d62024-12-11 19:37:06 +05303974 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3975 if err != nil {
3976 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3977 return err
3978 }
3979 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003980}
3981
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303982// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3983// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003984func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3985 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003986
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003987 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303988 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003989 return nil
3990 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003991 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003992
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003994 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3996 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003997 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003998 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003999
mpagenkof1fc3862021-02-16 10:09:52 +00004000 if aWriteToKvStore {
4001 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
4002 }
4003 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004004}
4005
dbainbri4d3a0dc2020-12-02 00:33:42 +00004006func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004007 defer cancel() //ensure termination of context (may be pro forma)
4008 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00004009 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004010 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00004011}
4012
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304013// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
4014//
4015// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00004016func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
4017 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
4018 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
4019 dh.mutexDeviceReason.Lock()
4020 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004021 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004022 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04004023 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024 DeviceId: dh.DeviceID,
4025 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04004026 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00004027 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004028 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004029 return err
4030 }
mpagenkoe4782082021-11-25 12:04:26 +00004031 } else {
4032 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 +00004033 }
mpagenkoe4782082021-11-25 12:04:26 +00004034 dh.deviceReason = deviceReason
4035 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
4036 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004037 return nil
4038}
4039
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004040func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
4041 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004042 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4044 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00004045 }
mpagenkof1fc3862021-02-16 10:09:52 +00004046 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00004047}
4048
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304049func (dh *deviceHandler) UpdateRebootPersData(ctx context.Context, flag bool) {
4050 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4051 if pDevEntry != nil {
4052 pDevEntry.MutexPersOnuConfig.Lock()
4053 pDevEntry.SOnuPersistentData.PersRebootInProgress = flag
4054 pDevEntry.MutexPersOnuConfig.Unlock()
4055 } else {
4056 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4057 }
4058}
4059
4060func (dh *deviceHandler) GetPersRebootFlag(ctx context.Context) bool {
4061 rebootFlag := false
4062 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
4063 if pDevEntry != nil {
4064 pDevEntry.MutexPersOnuConfig.RLock()
4065 rebootFlag = pDevEntry.SOnuPersistentData.PersRebootInProgress
4066 pDevEntry.MutexPersOnuConfig.RUnlock()
4067 } else {
4068 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4069 }
4070 return rebootFlag
4071}
4072
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004073// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03004074// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004075func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
4076 dh.lockDevice.RLock()
4077 defer dh.lockDevice.RUnlock()
4078 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03004080 }
4081 return 0, errors.New("error-fetching-uni-port")
4082}
Girish Gowdrae09a6202021-01-12 18:10:59 -08004083
4084// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004085func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4086 var errorsList []error
4087 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 -08004088
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004089 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
4090 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
4091 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
4092
4093 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
4094 // successfully.
4095 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
4096 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
4097 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004098 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 -08004099 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08004100 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004101 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004102 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08004103}
4104
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004105func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4106 var err error
4107 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004108 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004109
4110 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004111 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004112 errorsList = append(errorsList, err)
4113 }
4114 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004115 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00004116
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004117 return errorsList
4118}
4119
4120func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4121 var err error
4122 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004123 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004124 // Check if group metric related config is updated
4125 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004126 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4127 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
4128 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004129
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004130 if ok && m.Frequency != v.GroupFreq {
4131 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004132 errorsList = append(errorsList, err)
4133 }
4134 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004135 if ok && m.Enabled != v.Enabled {
4136 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004137 errorsList = append(errorsList, err)
4138 }
4139 }
4140 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004141 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004142 return errorsList
4143}
4144
4145func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
4146 var err error
4147 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004148 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004149 // Check if standalone metric related config is updated
4150 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
4152 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
4153 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004154
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004155 if ok && m.Frequency != v.SampleFreq {
4156 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004157 errorsList = append(errorsList, err)
4158 }
4159 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004160 if ok && m.Enabled != v.Enabled {
4161 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004162 errorsList = append(errorsList, err)
4163 }
4164 }
4165 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08004166 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004167 return errorsList
4168}
4169
4170// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004171func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004172 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08004173
4174 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07004175 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304176 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004177 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004178 // Initialize the next metric collection time.
4179 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
4180 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004181 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004182 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05304183 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
4184 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08004185 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05304186
Girish Gowdrae09a6202021-01-12 18:10:59 -08004187 select {
4188 case <-dh.stopCollector:
4189 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004190 // Stop the L2 PM FSM
4191 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
4193 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
4194 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004195 }
4196 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004197 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08004198 }
4199 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004200 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
4201 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004202 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004203 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
4204 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07004205 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08004206
Girish Gowdrae09a6202021-01-12 18:10:59 -08004207 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05304208 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004209 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
4210 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
4211 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
4212 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08004213 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004214 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
4215 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004216 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004217 } else {
4218 if dh.pmConfigs.Grouped { // metrics are managed as a group
4219 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004220 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08004221
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004222 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4223 // 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 -08004224 // 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 +00004225 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
4226 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004227 }
4228 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004229 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4230 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
4231 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
4232 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004233 }
4234 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004235 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004236
4237 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004238 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
4239 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
4240 // 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 -08004241 // 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 +00004242 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004243 prevInternal := g.NextCollectionInterval
4244 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004245 }
4246 }
4247 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004248 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
4249 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
4250 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07004251 prevInternal := m.NextCollectionInterval
4252 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004253 }
4254 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004255 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004256 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04004257 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08004258 } */
4259 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08004260 }
4261 }
4262}
kesavandfdf77632021-01-26 23:40:33 -05004263
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304264//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05304265func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
4266
4267 singleValResp := extension.SingleSetValueResponse{
4268 Response: &extension.SetValueResponse{
4269 Status: extension.SetValueResponse_OK,
4270 },
4271 }
4272
4273 return &singleValResp
4274}
4275
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004276func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05004277
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004278 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
4279 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05004280}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004281
Himani Chawla43f95ff2021-06-03 00:24:12 +05304282func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
4283 if dh.pOnuMetricsMgr == nil {
4284 return &extension.SingleGetValueResponse{
4285 Response: &extension.GetValueResponse{
4286 Status: extension.GetValueResponse_ERROR,
4287 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4288 },
4289 }
4290 }
Himani Chawlaee10b542021-09-20 16:46:40 +05304291 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05304292 return resp
4293}
4294
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00004295func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
4296
4297 var err error
4298 var pDevOmciCC *cmn.OmciCC
4299 if dh.pOnuOmciDevice == nil {
4300 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4301 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
4302 } else {
4303 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
4304 if pDevOmciCC == nil {
4305 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
4306 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
4307 }
4308 }
4309 if err != nil {
4310 return &extension.SingleGetValueResponse{
4311 Response: &extension.GetValueResponse{
4312 Status: extension.GetValueResponse_ERROR,
4313 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
4314 },
4315 },
4316 err
4317 }
4318 return pDevOmciCC.GetOmciCounters(), nil
4319}
4320
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304321//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004322func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
4323 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00004324 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004325 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004326 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004327}
4328
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004329func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00004330 var pAdapterFsm *cmn.AdapterFsm
4331 //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 +00004332 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004333 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004334 {
mpagenkofbf577d2021-10-12 11:44:33 +00004335 if dh.pOnuOmciDevice != nil {
4336 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
4337 } else {
4338 return true //FSM not active - so there is no activity on omci
4339 }
mpagenkof1fc3862021-02-16 10:09:52 +00004340 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004341 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004342 {
mpagenkofbf577d2021-10-12 11:44:33 +00004343 if dh.pOnuOmciDevice != nil {
4344 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
4345 } else {
4346 return true //FSM not active - so there is no activity on omci
4347 }
mpagenkof1fc3862021-02-16 10:09:52 +00004348 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004349 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004350 {
mpagenkofbf577d2021-10-12 11:44:33 +00004351 if dh.pLockStateFsm != nil {
4352 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4353 } else {
4354 return true //FSM not active - so there is no activity on omci
4355 }
mpagenkof1fc3862021-02-16 10:09:52 +00004356 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004357 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004358 {
mpagenkofbf577d2021-10-12 11:44:33 +00004359 if dh.pUnlockStateFsm != nil {
4360 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4361 } else {
4362 return true //FSM not active - so there is no activity on omci
4363 }
mpagenkof1fc3862021-02-16 10:09:52 +00004364 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004365 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004366 {
mpagenkofbf577d2021-10-12 11:44:33 +00004367 if dh.pOnuMetricsMgr != nil {
4368 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004369 } else {
4370 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004371 }
4372 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004373 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004374 {
4375 dh.lockUpgradeFsm.RLock()
4376 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004377 if dh.pOnuUpradeFsm != nil {
4378 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4379 } else {
4380 return true //FSM not active - so there is no activity on omci
4381 }
mpagenko80622a52021-02-09 16:53:23 +00004382 }
mpagenkof1fc3862021-02-16 10:09:52 +00004383 default:
4384 {
4385 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004386 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004387 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004388 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004389 }
mpagenkofbf577d2021-10-12 11:44:33 +00004390 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4391 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4392 }
4393 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004394}
4395
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004396func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4397 for _, v := range dh.pOnuTP.PAniConfigFsm {
4398 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004399 return false
4400 }
4401 }
4402 return true
4403}
4404
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304405//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004406func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004407 dh.lockVlanConfig.RLock()
4408 defer dh.lockVlanConfig.RUnlock()
4409 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004410 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004411 return false
4412 }
4413 }
4414 return true //FSM not active - so there is no activity on omci
4415}
4416
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304417//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004418func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4419 dh.lockVlanConfig.RLock()
4420 defer dh.lockVlanConfig.RUnlock()
4421 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004422 if v.PAdaptFsm.PFsm != nil {
4423 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004424 return true //there is at least one VLAN FSM with some active configuration
4425 }
4426 }
4427 }
4428 return false //there is no VLAN FSM with some active configuration
4429}
4430
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004431func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004432 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4433 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4434 return false
4435 }
4436 }
4437 // a further check is done to identify, if at least some data traffic related configuration exists
4438 // 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])
4439 return dh.checkUserServiceExists(ctx)
4440}
4441
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004442func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304443 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 +00004444 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004445 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004446 // TODO: fatal error reset ONU, delete deviceHandler!
4447 return
4448 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004449 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4450 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004451}
4452
4453func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4454 dh.mutexCollectorFlag.Lock()
4455 dh.collectorIsRunning = flagValue
4456 dh.mutexCollectorFlag.Unlock()
4457}
4458
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004459func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004460 dh.mutexCollectorFlag.RLock()
4461 flagValue := dh.collectorIsRunning
4462 dh.mutexCollectorFlag.RUnlock()
4463 return flagValue
4464}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304465
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304466func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4467 dh.mutextAlarmManagerFlag.Lock()
4468 dh.alarmManagerIsRunning = flagValue
4469 dh.mutextAlarmManagerFlag.Unlock()
4470}
4471
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004472func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304473 dh.mutextAlarmManagerFlag.RLock()
4474 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004475 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304476 dh.mutextAlarmManagerFlag.RUnlock()
4477 return flagValue
4478}
4479
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004480func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004481 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304482
4483 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004484 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304485 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304486 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304487 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304488 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004489 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4490 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304491 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304492 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004493 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4494 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304495 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304496 }
4497}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004498
Girish Gowdrae95687a2021-09-08 16:30:58 -07004499func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4500 dh.mutexFlowMonitoringRoutineFlag.Lock()
4501 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004502 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004503 dh.isFlowMonitoringRoutineActive[uniID] = flag
4504}
4505
4506func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4507 dh.mutexFlowMonitoringRoutineFlag.RLock()
4508 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4509 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004510 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304511 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4512 return dh.isFlowMonitoringRoutineActive[uniID]
4513 }
4514 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004515}
4516
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004517func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304518 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004519
Maninder7961d722021-06-16 22:10:28 +05304520 connectStatus := voltha.ConnectStatus_UNREACHABLE
4521 operState := voltha.OperStatus_UNKNOWN
4522
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004523 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004524 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004525 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004526 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004527 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004528 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304529 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004530 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4531 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4532 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4533 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4534 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4535 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4536 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4537 // However, a later refactoring of the functionality remains unaffected.
4538 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004539 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004540 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304541 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004542 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304543 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004544 onuDevEntry.MutexPersOnuConfig.RLock()
mgoudad611f4c2025-10-30 14:49:27 +05304545 switch onuDevEntry.SOnuPersistentData.PersOperState {
4546 case "up":
Maninderb5187552021-03-23 22:23:42 +05304547 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004548 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4549 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304550 operState = voltha.OperStatus_ACTIVE
4551 } else {
4552 operState = voltha.OperStatus_ACTIVATING
4553 }
4554 }
mgoudad611f4c2025-10-30 14:49:27 +05304555 case "down", "unknown", "":
Maninderb5187552021-03-23 22:23:42 +05304556 operState = voltha.OperStatus_DISCOVERED
4557 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004558 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004559 logger.Debugw(ctx, "Core DeviceStateUpdate",
4560 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304561 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304562 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004563 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004564 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004565 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004566 ConnStatus: connectStatus,
4567 OperStatus: operState,
4568 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304569 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004570 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304571 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004572 } else {
Maninderb5187552021-03-23 22:23:42 +05304573 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004574 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004576 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304577 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004578 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004579 } else {
4580 onuDevEntry.MutexPersOnuConfig.RLock()
4581 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4582 connectStatus = voltha.ConnectStatus_REACHABLE
4583 }
4584 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304585 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004586 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004587 }
mpagenko101ac942021-11-16 15:01:29 +00004588 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004589 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004590 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004591 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004593 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304594 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004595 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004596 } else {
4597 onuDevEntry.MutexPersOnuConfig.RLock()
4598 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4599 connectStatus = voltha.ConnectStatus_REACHABLE
4600 }
4601 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304602 }
4603
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004604 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304605
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004606 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004607 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004608 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004609 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004610 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004611
4612 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4613 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4614 } else {
4615 onuDevEntry.MutexReconciledTpInstances.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05304616 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]ia.TechProfileDownloadMessage)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004617 onuDevEntry.MutexReconciledTpInstances.Unlock()
4618 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004619 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004620 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004621 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304622 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004623 dh.reconciling = cSkipOnuConfigReconciling
4624 } else {
4625 dh.reconciling = cOnuConfigReconciling
4626 }
4627 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004628}
4629
mpagenko101ac942021-11-16 15:01:29 +00004630func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304631 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004632 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004633 dh.sendChReconcileFinished(success)
4634 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4635 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4636 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004637 } else {
mpagenko101ac942021-11-16 15:01:29 +00004638 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004639 }
4640}
4641
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004642func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004643 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004644 defer dh.mutexReconcilingFlag.RUnlock()
4645 return dh.reconciling != cNoReconciling
4646}
4647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004648func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004649 dh.mutexReconcilingFlag.RLock()
4650 defer dh.mutexReconcilingFlag.RUnlock()
4651 return dh.reconciling == cSkipOnuConfigReconciling
4652}
4653
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004654func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4655 dh.mutexReconcilingFirstPassFlag.Lock()
4656 dh.reconcilingFirstPass = value
4657 dh.mutexReconcilingFirstPassFlag.Unlock()
4658}
4659
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004660func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4661 dh.mutexReconcilingReasonUpdate.Lock()
4662 dh.reconcilingReasonUpdate = value
4663 dh.mutexReconcilingReasonUpdate.Unlock()
4664}
4665
4666func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4667 dh.mutexReconcilingReasonUpdate.RLock()
4668 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4669 return dh.reconcilingReasonUpdate
4670}
4671
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004672func (dh *deviceHandler) getDeviceReason() uint8 {
4673 dh.mutexDeviceReason.RLock()
4674 value := dh.deviceReason
4675 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004676 return value
4677}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004678
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004679func (dh *deviceHandler) GetDeviceReasonString() string {
4680 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004681}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004682
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004683func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004684 dh.mutexReadyForOmciConfig.Lock()
4685 dh.readyForOmciConfig = flagValue
4686 dh.mutexReadyForOmciConfig.Unlock()
4687}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004688func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004689 dh.mutexReadyForOmciConfig.RLock()
4690 flagValue := dh.readyForOmciConfig
4691 dh.mutexReadyForOmciConfig.RUnlock()
4692 return flagValue
4693}
Maninder7961d722021-06-16 22:10:28 +05304694
4695func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004696 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304697 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004698 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304699 }
4700
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004701 logger.Debugw(ctx, "Core DeviceStateUpdate",
4702 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004703 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004704 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004705 ConnStatus: connectStatus,
4706 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4707 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304708 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004709 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304710 }
4711}
khenaidoo7d3c5582021-08-11 18:09:44 -04004712
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05304713func (dh *deviceHandler) deviceRebootStateUpdate(ctx context.Context, techProfInstLoadFailed bool) {
4714 if techProfInstLoadFailed {
4715 if err := dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, true); err != nil {
4716 logger.Errorw(ctx, "unable to update device reason to core",
4717 log.Fields{"device-id": dh.DeviceID, "Err": err})
4718 }
4719 context := make(map[string]string)
4720 context["device-id"] = dh.DeviceID
4721 context["onu-serial-number"] = dh.device.SerialNumber
4722 context["parent-id"] = dh.parentID
4723
4724 // Send event on flow configuration failure so that corrective action can be triggered from NB
4725 deviceEvent := &voltha.DeviceEvent{
4726 ResourceId: dh.DeviceID,
4727 DeviceEventName: cmn.OnuFlowConfigFailed,
4728 Description: cmn.OnuFlowConfigFailedDesc,
4729 Context: context,
4730 }
4731 logger.Debugw(ctx, "send device event", log.Fields{"deviceEvent": deviceEvent, "device-id": dh.DeviceID})
4732 _ = dh.EventProxy.SendDeviceEvent(ctx, deviceEvent, voltha.EventCategory_EQUIPMENT, voltha.EventSubCategory_ONU, time.Now().Unix())
4733 }
4734}
4735
khenaidoo7d3c5582021-08-11 18:09:44 -04004736/*
4737Helper functions to communicate with Core
4738*/
4739
4740func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4741 cClient, err := dh.coreClient.GetCoreServiceClient()
4742 if err != nil || cClient == nil {
4743 return nil, err
4744 }
4745 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4746 defer cancel()
4747 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
mgoudad611f4c2025-10-30 14:49:27 +05304748 return cClient.GetDevice(subCtx, &common.ID{Id: deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04004749}
4750
khenaidoo42dcdfd2021-10-19 17:34:12 -04004751func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004752 cClient, err := dh.coreClient.GetCoreServiceClient()
4753 if err != nil || cClient == nil {
4754 return err
4755 }
4756 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4757 defer cancel()
4758 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004759 logger.Debugw(subCtx, "device-updated-in-core",
4760 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004761 return err
4762}
4763
4764func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4765 cClient, err := dh.coreClient.GetCoreServiceClient()
4766 if err != nil || cClient == nil {
4767 return err
4768 }
4769 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4770 defer cancel()
4771 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004772 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4773 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004774 return err
4775}
4776
4777func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4778 cClient, err := dh.coreClient.GetCoreServiceClient()
4779 if err != nil || cClient == nil {
4780 return err
4781 }
4782 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4783 defer cancel()
4784 _, err = cClient.DeviceUpdate(subCtx, device)
4785 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4786 return err
4787}
4788
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004789func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004790 cClient, err := dh.coreClient.GetCoreServiceClient()
4791 if err != nil || cClient == nil {
4792 return err
4793 }
4794 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4795 defer cancel()
4796 _, err = cClient.PortCreated(subCtx, port)
4797 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4798 return err
4799}
4800
khenaidoo42dcdfd2021-10-19 17:34:12 -04004801func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004802 cClient, err := dh.coreClient.GetCoreServiceClient()
4803 if err != nil || cClient == nil {
4804 return err
4805 }
4806 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4807 defer cancel()
4808 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004809 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"device-id": dh.device.Id, "port-state": portState, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004810 return err
4811}
4812
khenaidoo42dcdfd2021-10-19 17:34:12 -04004813func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004814 cClient, err := dh.coreClient.GetCoreServiceClient()
4815 if err != nil || cClient == nil {
4816 return err
4817 }
4818 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4819 defer cancel()
4820 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004821 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"device-id": dh.device.Id, "reason": reason, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004822 return err
4823}
4824
4825/*
4826Helper functions to communicate with parent adapter
4827*/
4828
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004829func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4830 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4831
4832 var request = ia.TechProfileInstanceRequestMessage{
4833 DeviceId: dh.DeviceID,
4834 TpInstancePath: aTpPath,
4835 ParentDeviceId: dh.parentID,
4836 ParentPonPort: dh.device.ParentPortNo,
4837 OnuId: dh.device.ProxyAddress.OnuId,
4838 UniId: uint32(aUniID),
4839 }
4840
4841 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004842 if err != nil || pgClient == nil {
4843 return nil, err
4844 }
4845 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4846 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004847 logger.Debugw(subCtx, "get-tech-profile-instance",
4848 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004849 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004850}
4851
Girish Gowdrae95687a2021-09-08 16:30:58 -07004852// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4853// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4854func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4855 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4856 dh.setFlowMonitoringIsRunning(uniID, true)
4857 for {
4858 select {
4859 // block on the channel to receive an incoming flow
4860 // process the flow completely before proceeding to handle the next flow
4861 case flowCb := <-dh.flowCbChan[uniID]:
4862 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304863 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004864 respChan := make(chan error)
4865 if flowCb.addFlow {
4866 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4867 } else {
4868 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4869 }
4870 // Block on response and tunnel it back to the caller
balaji.nagarajan62ac62b2025-09-08 10:49:58 +05304871 select {
4872
4873 case msg := <-respChan:
4874 *flowCb.respChan <- msg
4875 // response sent successfully
4876 logger.Info(flowCb.ctx, "serial-flow-processor--end",
4877 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4878 case <-flowCb.ctx.Done():
4879 logger.Info(flowCb.ctx, "flow handler context cancelled or timed out", log.Fields{"device-id": dh.DeviceID})
4880 // Optionally, you can handle cleanup or logging here
4881 if dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID] != nil && dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm != nil {
4882 pVlanFilterStatemachine := dh.UniVlanConfigFsmMap[flowCb.uniPort.UniID].PAdaptFsm.PFsm
4883 if pVlanFilterStatemachine != nil {
4884
4885 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
4886 logger.Warnw(flowCb.ctx, "UniVlanConfigFsm: can't reset",
4887 log.Fields{"device-id": dh.DeviceID, "err": err})
4888
4889 }
4890
4891 }
4892 }
4893
4894 ctx2 := context.Background()
4895 metadata := flow.GetMetadataFromWriteMetadataAction(ctx2, flowCb.flowItem)
4896 if metadata == 0 {
4897 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch metadata flow: %v",
4898 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4899 continue
4900 }
4901 TpID := flow.GetTechProfileIDFromWriteMetaData(ctx2, metadata)
4902
4903 if TpID == uint16(0) {
4904 logger.Warnw(flowCb.ctx, "AniConfigFsm: can't reset,failed to fetch techprofileid flow: %v",
4905 log.Fields{"device-id": dh.DeviceID, "flows": flowCb.flowItem})
4906 continue
4907 }
4908 if dh.pOnuTP != nil {
4909 // should always be the case here
4910 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
4911 if dh.pOnuTP.PAniConfigFsm != nil {
4912 uniTP := avcfg.UniTP{
4913 UniID: flowCb.uniPort.UniID,
4914 TpID: uint8(TpID),
4915 }
4916 if dh.pOnuTP.PAniConfigFsm[uniTP] != nil {
4917 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(context.Background())
4918 }
4919 }
4920 }
4921
4922 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07004923 case <-dh.stopFlowMonitoringRoutine[uniID]:
4924 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4925 dh.setFlowMonitoringIsRunning(uniID, false)
4926 return
4927 }
4928 }
4929}
4930
kesavand011d5162021-11-25 19:21:06 +05304931func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4932 request.ParentDeviceId = dh.GetProxyAddressID()
4933 request.ChildDeviceId = dh.DeviceID
4934 request.ProxyAddress = dh.GetProxyAddress()
4935 request.ConnectStatus = common.ConnectStatus_REACHABLE
4936
4937 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4938 if err != nil || pgClient == nil {
4939 return err
4940 }
4941 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4942 defer cancel()
4943 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4944 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4945 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004946 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4947 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304948 }
4949 return err
4950}
4951
khenaidoo42dcdfd2021-10-19 17:34:12 -04004952func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004953 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4954 if err != nil || pgClient == nil {
4955 return err
4956 }
4957 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4958 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004959 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004960 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004961 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4962 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004963 if status.Code(err) == codes.Unavailable {
4964 dh.setOltAvailable(false)
4965 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004966 logger.Errorw(ctx, "omci-failure",
4967 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004968 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004969 }
4970 return err
4971}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004972
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004973func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4974 // Check if there are additional TCONT instances necessary/available
4975 pDevEntry.MutexPersOnuConfig.Lock()
4976 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4977 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4978 pDevEntry.MutexPersOnuConfig.Unlock()
4979 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4980 logger.Debugw(ctx, "checking available TCONT instances",
4981 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4982 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4983 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4984 log.Fields{"device-id": dh.device.Id})
4985 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304986 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004987 }
4988 } else {
4989 pDevEntry.MutexPersOnuConfig.Unlock()
4990 }
4991 // Check if there are enough PrioQueue instances available
4992 if dh.pOnuTP != nil {
4993 var numberOfUsPrioQueueDbInsts int
4994
4995 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4996 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304997 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004998 numberOfUsPrioQueueDbInsts++
4999 }
5000 }
5001 // Check if there is an upstream PriorityQueue instance available for each Gem port
5002 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
5003 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
5004 log.Fields{"device-id": dh.DeviceID,
5005 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
5006 "tpInst.NumGemPorts": tpInst.NumGemPorts,
5007 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
5008
5009 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
5010 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
5011 log.Fields{"device-id": dh.device.Id})
5012 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05305013 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 +00005014 }
5015 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
5016 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
5017 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
5018 } else {
5019 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
5020 log.Fields{"device-id": dh.DeviceID})
5021 }
5022 return nil
5023}
5024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005025// GetDeviceID - TODO: add comment
5026func (dh *deviceHandler) GetDeviceID() string {
5027 return dh.DeviceID
5028}
5029
5030// GetProxyAddressID - TODO: add comment
5031func (dh *deviceHandler) GetProxyAddressID() string {
5032 return dh.device.ProxyAddress.GetDeviceId()
5033}
5034
5035// GetProxyAddressType - TODO: add comment
5036func (dh *deviceHandler) GetProxyAddressType() string {
5037 return dh.device.ProxyAddress.GetDeviceType()
5038}
5039
5040// GetProxyAddress - TODO: add comment
5041func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
5042 return dh.device.ProxyAddress
5043}
5044
5045// GetEventProxy - TODO: add comment
5046func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
5047 return dh.EventProxy
5048}
5049
5050// GetOmciTimeout - TODO: add comment
5051func (dh *deviceHandler) GetOmciTimeout() int {
5052 return dh.pOpenOnuAc.omciTimeout
5053}
5054
5055// GetAlarmAuditInterval - TODO: add comment
5056func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
5057 return dh.pOpenOnuAc.alarmAuditInterval
5058}
5059
5060// GetDlToOnuTimeout4M - TODO: add comment
5061func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
5062 return dh.pOpenOnuAc.dlToOnuTimeout4M
5063}
5064
5065// GetUniEntityMap - TODO: add comment
5066func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
5067 return &dh.uniEntityMap
5068}
5069
5070// GetPonPortNumber - TODO: add comment
5071func (dh *deviceHandler) GetPonPortNumber() *uint32 {
5072 return &dh.ponPortNumber
5073}
5074
5075// GetUniVlanConfigFsm - TODO: add comment
5076func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00005077 dh.lockVlanConfig.RLock()
5078 value := dh.UniVlanConfigFsmMap[uniID]
5079 dh.lockVlanConfig.RUnlock()
5080 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005081}
5082
5083// GetOnuAlarmManager - TODO: add comment
5084func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
5085 return dh.pAlarmMgr
5086}
5087
5088// GetOnuMetricsManager - TODO: add comment
5089func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
5090 return dh.pOnuMetricsMgr
5091}
5092
5093// GetOnuTP - TODO: add comment
5094func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
5095 return dh.pOnuTP
5096}
5097
5098// GetBackendPathPrefix - TODO: add comment
5099func (dh *deviceHandler) GetBackendPathPrefix() string {
5100 return dh.pOpenOnuAc.cm.Backend.PathPrefix
5101}
5102
5103// GetOnuIndication - TODO: add comment
mgoudad611f4c2025-10-30 14:49:27 +05305104func (dh *deviceHandler) GetOnuIndication() *oop.OnuIndication {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005105 return dh.pOnuIndication
5106}
5107
5108// RLockMutexDeletionInProgressFlag - TODO: add comment
5109func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
5110 dh.mutexDeletionInProgressFlag.RLock()
5111}
5112
5113// RUnlockMutexDeletionInProgressFlag - TODO: add comment
5114func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
5115 dh.mutexDeletionInProgressFlag.RUnlock()
5116}
5117
5118// GetDeletionInProgress - TODO: add comment
5119func (dh *deviceHandler) GetDeletionInProgress() bool {
5120 return dh.deletionInProgress
5121}
5122
5123// GetPmConfigs - TODO: add comment
5124func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
5125 return dh.pmConfigs
5126}
5127
5128// GetDeviceType - TODO: add comment
5129func (dh *deviceHandler) GetDeviceType() string {
5130 return dh.DeviceType
5131}
5132
5133// GetLogicalDeviceID - TODO: add comment
5134func (dh *deviceHandler) GetLogicalDeviceID() string {
5135 return dh.logicalDeviceID
5136}
5137
5138// GetDevice - TODO: add comment
5139func (dh *deviceHandler) GetDevice() *voltha.Device {
5140 return dh.device
5141}
5142
Holger Hildebrandt2b107642022-12-09 07:56:23 +00005143func (dh *deviceHandler) setOltAvailable(value bool) {
5144 dh.mutexOltAvailable.Lock()
5145 dh.oltAvailable = value
5146 dh.mutexOltAvailable.Unlock()
5147}
5148
5149// IsOltAvailable - TODO: add comment
5150func (dh *deviceHandler) IsOltAvailable() bool {
5151 dh.mutexOltAvailable.RLock()
5152 defer dh.mutexOltAvailable.RUnlock()
5153 return dh.oltAvailable
5154}
5155
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005156// GetMetricsEnabled - TODO: add comment
5157func (dh *deviceHandler) GetMetricsEnabled() bool {
5158 return dh.pOpenOnuAc.MetricsEnabled
5159}
5160
Holger Hildebrandtc572e622022-06-22 09:19:17 +00005161// GetExtendedOmciSupportEnabled - TODO: add comment
5162func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
5163 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
5164}
5165
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05305166// GetExtendedOmciSupportEnabled - TODO: add comment
5167func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
5168 return dh.pOpenOnuAc.skipOnuConfig
5169}
5170
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05305171func (dh *deviceHandler) GetDeviceTechProfOnReboot() bool {
5172 return dh.pOpenOnuAc.CheckDeviceTechProfOnReboot
5173}
5174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00005175// InitPmConfigs - TODO: add comment
5176func (dh *deviceHandler) InitPmConfigs() {
5177 dh.pmConfigs = &voltha.PmConfigs{}
5178}
5179
5180// GetUniPortMask - TODO: add comment
5181func (dh *deviceHandler) GetUniPortMask() int {
5182 return dh.pOpenOnuAc.config.UniPortMask
5183}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00005184
5185func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
5186 tpPathFound := false
5187 for _, tpPath := range aTpPathMap {
5188 if tpPath != "" {
5189 tpPathFound = true
5190 }
5191 }
5192 return tpPathFound
5193}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005194
praneeth nalmas5a0a5502022-12-23 15:57:00 +05305195func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
5196 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
5197 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
5198 return resp
5199}
5200
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05305201// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
5202func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
5203 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
pnalmas6d6b7d72025-10-23 16:34:22 +05305204 logger.Debugw(ctx, "Received response from ONU Metrics Manager for GEM Stats", log.Fields{"device-id": dh.DeviceID})
5205 return resp
5206}
5207
5208// getOnuFECStats - Get the GEM PM history data of the request ONT device
5209func (dh *deviceHandler) getOnuFECStats(ctx context.Context) *extension.SingleGetValueResponse {
5210 resp := dh.pOnuMetricsMgr.GetONUFECCounters(ctx)
5211 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 +05305212 return resp
5213}
5214
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05305215func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
5216 return dh.deviceDeleteCommChan
5217}
5218
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005219// PrepareForGarbageCollection - remove references to prepare for garbage collection
5220func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
5221 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
5222
5223 // Note: This function must be called as a goroutine to prevent blocking of further processing!
5224 // first let the objects rest for some time to give all asynchronously started
5225 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00005226 time.Sleep(2 * time.Second)
5227
5228 if dh.pOnuOmciDevice != nil {
5229 if dh.pOnuOmciDevice.PDevOmciCC != nil {
5230 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
5231 // reset handling (even in future coding), request monitoring is canceled here one last time to
5232 // be sure that all corresponding go routines are terminated
5233 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
5234 }
5235 }
5236 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005237
5238 if dh.pOnuTP != nil {
5239 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
5240 }
5241 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005242 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
5243 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07005244 select {
5245 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
5246 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
5247 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
5248 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00005249 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07005250 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005251 }
5252 if dh.pAlarmMgr != nil {
5253 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
5254 }
5255 if dh.pSelfTestHdlr != nil {
5256 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
5257 }
5258 if dh.pLockStateFsm != nil {
5259 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5260 }
5261 if dh.pUnlockStateFsm != nil {
5262 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5263 }
5264 if dh.pOnuUpradeFsm != nil {
5265 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
5266 }
5267 if dh.pOnuOmciDevice != nil {
5268 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
5269 }
5270 for k, v := range dh.UniVlanConfigFsmMap {
5271 v.PrepareForGarbageCollection(ctx, aDeviceID)
5272 delete(dh.UniVlanConfigFsmMap, k)
5273 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05305274 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00005275 dh.pOnuOmciDevice = nil
5276 dh.pOnuTP = nil
5277 dh.pOnuMetricsMgr = nil
5278 dh.pAlarmMgr = nil
5279 dh.pSelfTestHdlr = nil
5280 dh.pLockStateFsm = nil
5281 dh.pUnlockStateFsm = nil
5282 dh.pOnuUpradeFsm = nil
5283}