blob: fc5efeff1379f4282a03ca37a56158c852959fa9 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth nalmas5a0a5502022-12-23 15:57:00 +053017// Package core provides the utility for onu devices, flows and statistics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040049 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040050 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000051 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040052 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000056 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040057 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt2b107642022-12-09 07:56:23 +000058 "google.golang.org/grpc/codes"
59 "google.golang.org/grpc/status"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060)
61
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000062const (
mpagenko101ac942021-11-16 15:01:29 +000063 //constants for reconcile flow check channel
64 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
65 cWaitReconcileFlowAbortOnError = 0xFFFE
66 cWaitReconcileFlowNoActivity = 0xFFFF
67)
68
69const (
70 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000071 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000072)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000073
mpagenko1cc3cb42020-07-27 15:24:38 +000074const (
mpagenko44bd8362021-11-15 11:40:05 +000075 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
76 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
77 // as long as such is not available by the libraries - use this workaround
78 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
79)
80
81const (
mpagenko1cc3cb42020-07-27 15:24:38 +000082 // events of Device FSM
83 devEvDeviceInit = "devEvDeviceInit"
84 devEvGrpcConnected = "devEvGrpcConnected"
85 devEvGrpcDisconnected = "devEvGrpcDisconnected"
86 devEvDeviceUpInd = "devEvDeviceUpInd"
87 devEvDeviceDownInd = "devEvDeviceDownInd"
88)
89const (
90 // states of Device FSM
91 devStNull = "devStNull"
92 devStDown = "devStDown"
93 devStInit = "devStInit"
94 devStConnected = "devStConnected"
95 devStUp = "devStUp"
96)
97
praneeth nalmas5a0a5502022-12-23 15:57:00 +053098// Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
Holger Hildebrandt24d51952020-05-04 14:03:42 +000099const (
Himani Chawla4d908332020-08-31 12:30:20 +0530100 pon = voltha.EventSubCategory_PON
101 //olt = voltha.EventSubCategory_OLT
102 //ont = voltha.EventSubCategory_ONT
103 //onu = voltha.EventSubCategory_ONU
104 //nni = voltha.EventSubCategory_NNI
105 //service = voltha.EventCategory_SERVICE
106 //security = voltha.EventCategory_SECURITY
107 equipment = voltha.EventCategory_EQUIPMENT
108 //processing = voltha.EventCategory_PROCESSING
109 //environment = voltha.EventCategory_ENVIRONMENT
110 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000111)
112
113const (
114 cEventObjectType = "ONU"
115)
116const (
117 cOnuActivatedEvent = "ONU_ACTIVATED"
118)
119
mpagenkof1fc3862021-02-16 10:09:52 +0000120type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000122 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000123}
124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000125var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
126 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
127 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
128 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
129 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
130 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
131 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
132 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
133 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000134}
135
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000136const (
137 cNoReconciling = iota
138 cOnuConfigReconciling
139 cSkipOnuConfigReconciling
140)
141
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142// FlowCb is the flow control block containing flow add/delete information along with a response channel
143type FlowCb struct {
144 ctx context.Context // Flow handler context
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 flowItem *of.OfpFlowStats
146 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400147 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700148 respChan *chan error // channel to report the Flow handling error
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530149 addFlow bool // if true flow to be added, else removed
Girish Gowdrae95687a2021-09-08 16:30:58 -0700150}
151
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530152// deviceHandler will interact with the ONU ? device.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153type deviceHandler struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530154 EventProxy eventif.EventProxy
155
156 device *voltha.Device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157
khenaidoo7d3c5582021-08-11 18:09:44 -0400158 coreClient *vgrpc.Client
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000159
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800160 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400161 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800162
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163 pOpenOnuAc *OpenONUAC
164 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530165 //pPonPort *voltha.Port
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530166 deviceEntrySet chan bool //channel for DeviceEntry set event
167 pOnuOmciDevice *mib.OnuDeviceEntry
168 pOnuTP *avcfg.OnuUniTechProf
169 pOnuMetricsMgr *pmmgr.OnuMetricsManager
170 pAlarmMgr *almgr.OnuAlarmManager
171 pSelfTestHdlr *otst.SelfTestControlBlock
172 exitChannel chan int
173 pOnuIndication *oop.OnuIndication
174 pLockStateFsm *uniprt.LockStateFsm
175 pUnlockStateFsm *uniprt.LockStateFsm
176
177 stopCollector chan bool
178 stopAlarmManager chan bool
179 stopHeartbeatCheck chan bool
180 uniEntityMap cmn.OnuUniPortMap
181 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
182 pOnuUpradeFsm *swupg.OnuUpgradeFsm
183 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
184 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
185 pLastUpgradeImageState *voltha.ImageState
186 upgradeFsmChan chan struct{}
187
188 deviceDeleteCommChan chan bool
189 DeviceID string
190 DeviceType string
191 adminState string
192 logicalDeviceID string
193 ProxyAddressID string
194 ProxyAddressType string
195 parentID string
196
197 flowCbChan []chan FlowCb
198 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
199 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
200 reconcileExpiryComplete time.Duration
201 reconcileExpiryVlanConfig time.Duration
202 lockDevice sync.RWMutex
203 mutexDeviceReason sync.RWMutex
204 mutexCollectorFlag sync.RWMutex
205 mutextAlarmManagerFlag sync.RWMutex
206 lockVlanConfig sync.RWMutex
207 lockVlanAdd sync.RWMutex
208 lockUpgradeFsm sync.RWMutex
209 mutexReconcilingFlag sync.RWMutex
210 mutexReconcilingFirstPassFlag sync.RWMutex
211 mutexReconcilingReasonUpdate sync.RWMutex
212 mutexReadyForOmciConfig sync.RWMutex
213 mutexDeletionInProgressFlag sync.RWMutex
214 mutexFlowMonitoringRoutineFlag sync.RWMutex
215 mutexForDisableDeviceRequested sync.RWMutex
216 mutexOltAvailable sync.RWMutex
217 mutexKvStoreContext sync.Mutex
218 ponPortNumber uint32
219
220 deviceReason uint8
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000221
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222 //flowMgr *OpenOltFlowMgr
223 //eventMgr *OpenOltEventMgr
224 //resourceMgr *rsrcMgr.OpenOltResourceMgr
225
226 //discOnus sync.Map
227 //onus sync.Map
228 //portStats *OpenOltStatisticsMgr
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530229 collectorIsRunning bool
230 alarmManagerIsRunning bool
231 upgradeCanceled bool
232 reconciling uint8
233 reconcilingFirstPass bool
234 reconcilingReasonUpdate bool
235 readyForOmciConfig bool
236 deletionInProgress bool
237 disableDeviceRequested bool // this flag identify ONU received disable request or not
238 oltAvailable bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239}
240
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530241// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400242func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530243 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400244 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400246 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000249 dh.DeviceType = cloned.Type
250 dh.adminState = "up"
251 dh.device = cloned
252 dh.pOpenOnuAc = adapter
253 dh.exitChannel = make(chan int, 1)
254 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000255 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000256 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000257 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530258 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530259 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260 dh.stopHeartbeatCheck = make(chan bool, 2)
261 //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 +0000262 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000264 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000265 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000266 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300267 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000268 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000269 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000270 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000271 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300272 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000273 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000274 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000275 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
276 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
277 if rECSeconds < 2 {
278 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
279 rECSeconds = 2
280 }
281 rEVCSeconds := rECSeconds / 2
282 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000283 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000284 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000285 dh.pLastUpgradeImageState = &voltha.ImageState{
286 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
287 Reason: voltha.ImageState_UNKNOWN_ERROR,
288 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
289 }
290 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530291 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800293 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
294 dh.pmConfigs = cloned.PmConfigs
295 } /* else {
296 // will be populated when onu_metrics_mananger is initialized.
297 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800298
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000299 // Device related state machine
300 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000301 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000303 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
304 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
305 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
306 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
307 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308 },
309 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
311 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
312 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
313 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
314 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
315 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
316 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
317 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 },
319 )
mpagenkoaf801632020-07-03 10:00:42 +0000320
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 return &dh
322}
323
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324// start save the device to the data model
325func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000326 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000328 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329}
330
Himani Chawla4d908332020-08-31 12:30:20 +0530331/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530333func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334 logger.Debug("stopping-device-handler")
335 dh.exitChannel <- 1
336}
Himani Chawla4d908332020-08-31 12:30:20 +0530337*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338
339// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530340// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530342// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530343func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400344 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000346 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530347
mpagenko1cc3cb42020-07-27 15:24:38 +0000348 if dh.pDeviceStateFsm.Is(devStNull) {
349 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000350 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 +0000351 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000352 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800353 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
354 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800355 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400356 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000357 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800358 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800359 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000362 }
363
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000364}
365
khenaidoo42dcdfd2021-10-19 17:34:12 -0400366func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000367 /* 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 +0530368 //assuming omci message content is hex coded!
369 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000372 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000373 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000375 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000377 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000378 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
379 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000381 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
382 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530383}
384
khenaidoo42dcdfd2021-10-19 17:34:12 -0400385func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000387
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000389 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000390 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
391 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530393 if dh.pOnuTP == nil {
394 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000395 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000396 log.Fields{"device-id": dh.DeviceID})
397 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530398 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 if !dh.IsReadyForOmciConfig() {
400 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
401 "device-state": dh.GetDeviceReasonString()})
402 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530403 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000404 //previous state test here was just this one, now extended for more states to reject the SetRequest:
405 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
406 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530407
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
410 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000411 dh.pOnuTP.LockTpProcMutex()
412 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413
mpagenko44bd8362021-11-15 11:40:05 +0000414 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530415 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
416 techProfMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417 }
418 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000419 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800420 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000421 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
422 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800423 return err
424 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000425 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
426 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000427
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000428 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530429
Girish Gowdra50e56422021-06-01 16:46:04 -0700430 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400431 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000432 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
433 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000434
435 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
436 if err != nil {
437 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
438 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
439 // stopping all further processing
440 _ = dh.UpdateInterface(ctx)
441 return err
442 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700443 // if there has been some change for some uni TechProfilePath
444 //in order to allow concurrent calls to other dh instances we do not wait for execution here
445 //but doing so we can not indicate problems to the caller (who does what with that then?)
446 //by now we just assume straightforward successful execution
447 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
448 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530449
Girish Gowdra50e56422021-06-01 16:46:04 -0700450 // deadline context to ensure completion of background routines waited for
451 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
452 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
453 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700456
457 var wg sync.WaitGroup
458 wg.Add(1) // for the 1 go routine to finish
459 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700461 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000462 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
463 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 -0700464 return tpErr
465 }
466 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
467 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530468 defer cancel2()
469 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
470 if err1 != nil {
471 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
472 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700473 }
474 return nil
475 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000476 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700477 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700478 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000481 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
482 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 return nil
484}
485
khenaidoo42dcdfd2021-10-19 17:34:12 -0400486func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000487 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530488
489 if dh.pOnuTP == nil {
490 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 log.Fields{"device-id": dh.DeviceID})
493 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530495 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 dh.pOnuTP.LockTpProcMutex()
497 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530498
mpagenko0f543222021-11-03 16:24:14 +0000499 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
500 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
501 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530502 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
503 delGemPortMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504 }
505 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800507 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000508 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
509 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800510 return err
511 }
mpagenko0f543222021-11-03 16:24:14 +0000512 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
513 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000514 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000515
Mahir Gunyel9545be22021-07-04 15:53:16 -0700516 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000517 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518
Himani Chawla26e555c2020-08-31 12:30:20 +0530519}
520
khenaidoo42dcdfd2021-10-19 17:34:12 -0400521func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000522 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 +0000523
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000526 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
527 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000528 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 if dh.pOnuTP == nil {
530 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 log.Fields{"device-id": dh.DeviceID})
533 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 }
535
Himani Chawla26e555c2020-08-31 12:30:20 +0530536 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000537 dh.pOnuTP.LockTpProcMutex()
538 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539
mpagenko0f543222021-11-03 16:24:14 +0000540 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
541 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
542 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530543 return fmt.Errorf("received UniId value exceeds range: %d, device-id: %s",
544 delTcontMsg.UniId, dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545 }
546 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700547 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000548 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800549 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000550 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
551 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800552 return err
553 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000554 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530555
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000556 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
557 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530558 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000559 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 +0530560 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
561 if err1 != nil {
562 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
563 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000564 }
565
Mahir Gunyel9545be22021-07-04 15:53:16 -0700566 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000568
Mahir Gunyel9545be22021-07-04 15:53:16 -0700569}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000570
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
573 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700574 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
576 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530577 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700578 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700580 resourceName = "Gem"
581 } else {
582 resourceName = "Tcont"
583 }
584
585 // deadline context to ensure completion of background routines waited for
586 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
587 dctx, cancel := context.WithDeadline(context.Background(), deadline)
588
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700590
591 var wg sync.WaitGroup
592 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700594 resource, entryID, &wg)
595 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
597 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700598 return err
599 }
600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
602 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
603 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
604 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700605 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530606 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700607 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000608 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 +0530609 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
610 if err != nil {
611 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700612 return err
613 }
614 }
615 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700617 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530618 return nil
619}
620
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530621// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400623 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400624 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
626 var errorsList []error
627 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000628 //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 +0000629 if apOfFlowChanges.ToRemove != nil {
630 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000631 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 "device-id": dh.DeviceID})
634 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700635 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000636 continue
637 }
638 flowInPort := flow.GetInPort(flowItem)
639 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
641 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700642 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000643 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000645 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000646 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 } else {
651 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000653 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
654 loUniPort = uniPort
655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000658 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700660 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000661 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000662 }
663 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000664 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
666 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700667
668 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
669 // Step1 : Fill flowControlBlock
670 // Step2 : Push the flowControlBlock to ONU channel
671 // Step3 : Wait on response channel for response
672 // Step4 : Return error value
673 startTime := time.Now()
674 respChan := make(chan error)
675 flowCb := FlowCb{
676 ctx: ctx,
677 addFlow: false,
678 flowItem: flowItem,
679 flowMetaData: nil,
680 uniPort: loUniPort,
681 respChan: &respChan,
682 }
683 dh.flowCbChan[loUniPort.UniID] <- flowCb
684 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
685 // Wait on the channel for flow handlers return value
686 retError = <-respChan
687 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
688 if retError != nil {
689 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
690 log.Fields{"device-id": dh.DeviceID, "error": retError})
691 errorsList = append(errorsList, retError)
692 continue
693 }
694 } else {
695 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
696 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000697 }
698 }
699 }
700 }
mpagenko01e726e2020-10-23 09:45:29 +0000701 if apOfFlowChanges.ToAdd != nil {
702 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
703 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 "device-id": dh.DeviceID})
706 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700707 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000708 continue
709 }
710 flowInPort := flow.GetInPort(flowItem)
711 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
713 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700714 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000715 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000717 } else if flowInPort == dh.ponPortNumber {
718 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000719 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000721 continue
722 } else {
723 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000724 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000725 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
726 loUniPort = uniPort
727 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000730 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700732 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000733 continue
mpagenko01e726e2020-10-23 09:45:29 +0000734 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000735 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
736 // if not, we just throw some error here to have an indication about that, if we really need to support that
737 // then we would need to create some means to activate the internal stored flows
738 // after the device gets active automatically (and still with its dependency to the TechProfile)
739 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
740 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000741 if !dh.IsReadyForOmciConfig() {
742 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
743 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700744 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
745 errorsList = append(errorsList, retError)
746 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000747 }
748
mpagenko01e726e2020-10-23 09:45:29 +0000749 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000751 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
752 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700753 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
754 // Step1 : Fill flowControlBlock
755 // Step2 : Push the flowControlBlock to ONU channel
756 // Step3 : Wait on response channel for response
757 // Step4 : Return error value
758 startTime := time.Now()
759 respChan := make(chan error)
760 flowCb := FlowCb{
761 ctx: ctx,
762 addFlow: true,
763 flowItem: flowItem,
764 flowMetaData: apFlowMetaData,
765 uniPort: loUniPort,
766 respChan: &respChan,
767 }
768 dh.flowCbChan[loUniPort.UniID] <- flowCb
769 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
770 // Wait on the channel for flow handlers return value
771 retError = <-respChan
772 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
773 if retError != nil {
774 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
775 log.Fields{"device-id": dh.DeviceID, "error": retError})
776 errorsList = append(errorsList, retError)
777 continue
778 }
779 } else {
780 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
781 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000782 }
783 }
784 }
785 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700786 if len(errorsList) > 0 {
787 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
788 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
789 }
790 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000791}
792
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530793// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
794// following are the expected device states after this activity:
795// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000796// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
798 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300799 dh.mutexForDisableDeviceRequested.Lock()
800 dh.disableDeviceRequested = true
801 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000802 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000803 //note that disableDevice sequences in some 'ONU active' state may yield also
804 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000805 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000807 //disable-device shall be just a UNi/ONU-G related admin state setting
808 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000811 // disable UNI ports/ONU
812 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
813 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000815 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000816 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000818 }
819 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000820 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000821 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000822 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400823 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000825 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400826 OperStatus: voltha.OperStatus_UNKNOWN,
827 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000828 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000830 }
mpagenko01e726e2020-10-23 09:45:29 +0000831 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000832
833 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000834 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000835 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300836 }
837}
838
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530839// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
841 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000842
mpagenkoaa3afe92021-05-21 16:20:58 +0000843 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000844 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
845 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
846 // for real ONU's that should have nearly no influence
847 // Note that for real ONU's there is anyway a problematic situation with following sequence:
848 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
849 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
850 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000852
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000853 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300855 dh.mutexForDisableDeviceRequested.Lock()
856 dh.disableDeviceRequested = false
857 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000858 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000860 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000863 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300864}
865
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530867 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000868
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000870 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 return
873 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000875 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000877 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000879 }
mpagenko101ac942021-11-16 15:01:29 +0000880 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000881 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000882 }
Himani Chawla4d908332020-08-31 12:30:20 +0530883 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000884 pDevEntry.MutexPersOnuConfig.RLock()
885 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
886 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
887 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
888 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
889 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000891}
892
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000893func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530894 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000895
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000896 continueWithFlowConfig := false
897
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000900 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000901 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
902 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 dh.pOnuTP.LockTpProcMutex()
905 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000907 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000908 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
910 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530911 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000913 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
914 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000915 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000916 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700917 techProfsFound := false
918 techProfInstLoadFailed := false
919outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000920 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000921 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000922 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000923 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000924 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000925 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000927 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
929 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000930 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000931 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000932 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700933 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000934 var iaTechTpInst ia.TechProfileDownloadMessage
935 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800936 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 pDevEntry.MutexReconciledTpInstances.RLock()
938 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
939 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000940 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000941 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000943 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 break outerLoop
945 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000946 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000947 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700948 var tpInst tech_profile.TechProfileInstance
949 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400950 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700951 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000952 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700954 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000955 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700957 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
958 break outerLoop
959 }
960
Girish Gowdra041dcb32020-11-16 16:54:30 -0800961 // deadline context to ensure completion of background routines waited for
962 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
963 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000965
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800967 var wg sync.WaitGroup
968 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000970 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
972 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700973 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
974 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800975 }
mpagenko2dc896e2021-08-02 12:03:59 +0000976 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000977 if len(uniData.PersFlowParams) != 0 {
978 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000979 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000981 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 } // for all UNI entries from SOnuPersistentData
983 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
984 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985 }
mpagenko2dc896e2021-08-02 12:03:59 +0000986
987 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
988 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000989
990 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000991}
992
993func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
994 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
995 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530996 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000997 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000998 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 return
1000 }
mpagenko2dc896e2021-08-02 12:03:59 +00001001 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001002 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001003 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001004 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001005 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001006 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001007 }
mpagenko2dc896e2021-08-02 12:03:59 +00001008 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301009 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001011 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001012 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013}
1014
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1016 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001018 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001020 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001021 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001022 return
1023 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 pDevEntry.MutexPersOnuConfig.RLock()
1026 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1027 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301028 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001030 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001031 return
1032 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001033 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001034 var uniVlanConfigEntries []uint8
1035 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1036
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001038 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1039 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001040 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 continue
1043 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001044 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001045 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001047 // It doesn't make sense to configure any flows if no TPs are available
1048 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001049 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001050 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1051 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001052 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001054
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001057 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1060 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001061 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001062 return
1063 }
mpagenko101ac942021-11-16 15:01:29 +00001064 //needed to split up function due to sca complexity
1065 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1066
mpagenko2dc896e2021-08-02 12:03:59 +00001067 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001068 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1070 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001071 // this can't be used as global finished reconciling flag because
1072 // assumes is getting called before the state machines for the last flow is completed,
1073 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1075 } // for all UNI entries from SOnuPersistentData
1076 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001077
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001078 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301079 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001080 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001081 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001082 return
1083 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001084 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1085 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1086 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1087 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1088 log.Fields{"device-id": dh.DeviceID})
1089 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1090 if pDevEntry != nil {
1091 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001092 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001093 } else {
1094 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1095 log.Fields{"device-id": dh.DeviceID})
1096 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1097 if pDevEntry != nil {
1098 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1099 }
1100 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001101 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001102 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103}
1104
mpagenko101ac942021-11-16 15:01:29 +00001105func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1106 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1107 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1108 flowsProcessed := 0
1109 lastFlowToReconcile := false
1110 loUniID := apUniPort.UniID
1111 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001112 if !(*apFlowsFound) {
1113 *apFlowsFound = true
1114 syncChannel := make(chan struct{})
1115 // start go routine with select() on reconciling vlan config channel before
1116 // starting vlan config reconciling process to prevent loss of any signal
1117 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1118 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1119 //block until the wait routine is really blocked on channel input
1120 // in order to prevent to early ready signal from VlanConfig processing
1121 <-syncChannel
1122 }
1123 if flowsProcessed == len(aPersFlowParam)-1 {
1124 var uniAdded bool
1125 lastFlowToReconcile = true
1126 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1127 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001128 }
1129 }
mpagenko101ac942021-11-16 15:01:29 +00001130 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1131 "device-id": dh.DeviceID, "uni-id": loUniID,
1132 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1133 dh.lockVlanConfig.Lock()
1134 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1135 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1136 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301137 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid), uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001138 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1139 }
1140 } else {
1141 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301142 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301143 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001144 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1145 }
1146 }
1147 dh.lockVlanConfig.Unlock()
1148 flowsProcessed++
1149 } //for all flows of this UNI
1150}
1151
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301152// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1153//
1154// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001155func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1156 waitGroup *cmn.WaitGroupWithTimeOut) {
1157 var reconciledUniVlanConfigEntries []uint8
1158 var appended bool
1159 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1160 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1161 "device-id": dh.DeviceID, "expiry": expiry})
1162 // indicate blocking on channel now to the caller
1163 aSyncChannel <- struct{}{}
1164 for {
1165 select {
1166 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1167 switch uniIndication {
1168 // no activity requested (should normally not be received) - just continue waiting
1169 case cWaitReconcileFlowNoActivity:
1170 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1171 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301172 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001173 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1174 return
1175 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1176 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301177 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001178 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1179 return
1180 // this should be a valid UNI vlan config done indication
1181 default:
1182 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301183 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001184 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1185 if reconciledUniVlanConfigEntries, appended =
1186 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1187 waitGroup.Done()
1188 }
1189 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301190 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 +00001191 }
1192 } //switch uniIndication
1193
1194 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1195 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1196 log.Fields{"device-id": dh.DeviceID})
1197 return
1198 }
1199 }
1200}
1201
1202func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1203 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1204}
1205
1206func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1207 for _, ele := range slice {
1208 if ele == val {
1209 return slice, false
1210 }
1211 }
1212 return append(slice, val), true
1213}
1214
1215// sendChReconcileFinished - sends true or false on reconcileFinish channel
1216func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1217 if dh != nil { //if the object still exists (might have been already deleted in background)
1218 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1219 select {
1220 case dh.chReconcilingFinished <- success:
1221 default:
1222 }
1223 }
1224}
1225
1226// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1227func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1228 if dh != nil { //if the object still exists (might have been already deleted in background)
1229 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1230 select {
1231 case dh.chUniVlanConfigReconcilingDone <- value:
1232 default:
1233 }
1234 }
1235}
1236
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001241 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001242 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001243 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001244 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001245 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001246
1247 // deadline context to ensure completion of background routines waited for
1248 //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 +05301249 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301251 defer cancel()
1252 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1253 if err != nil {
1254 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1255 return err
1256 }
1257 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001258}
1259
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301260// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001261// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301262//
1263// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1264//
1265// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001266func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001268 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001270 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001271 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301273 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001275 return
Himani Chawla4d908332020-08-31 12:30:20 +05301276 }
mpagenko01e726e2020-10-23 09:45:29 +00001277
1278 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001280
mpagenko44bd8362021-11-15 11:40:05 +00001281 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001283 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001284 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001286 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001287 OperStatus: voltha.OperStatus_DISCOVERED,
1288 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001289 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001291 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001292 }
mpagenkoe4782082021-11-25 12:04:26 +00001293 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001294 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001295 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001297 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1298 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1299 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1300 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001301}
1302
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301303// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1304//
1305// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001306func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001307 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001308 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001309 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001310
1311 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001312 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001313 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1315 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001316 }
1317
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001319 var inactiveImageID uint16
1320 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1321 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001322 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1323 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001324 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001326 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001327 if err == nil {
1328 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1329 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001330 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001331 }
1332 } else {
1333 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001335 }
mpagenko15ff4a52021-03-02 10:09:20 +00001336 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001337 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001338 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001339 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1340 dh.upgradeCanceled = true
1341 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1342 }
mpagenko38662d02021-08-11 09:45:19 +00001343 //no effort spent anymore for the old API to automatically cancel and restart the download
1344 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001345 }
mpagenko15ff4a52021-03-02 10:09:20 +00001346 } else {
1347 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001349 }
1350 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1352 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001353 }
1354 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001355}
1356
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301357// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001358// after the OnuImage has been downloaded to the adapter, called in background
1359func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001361
1362 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001366 return
1367 }
1368
1369 var inactiveImageID uint16
1370 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1371 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001372 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001373
mpagenko59862f02021-10-11 08:53:18 +00001374 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001375 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001376 // but must be still locked at calling createOnuUpgradeFsm
1377 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1378 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1379 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001380 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1381 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001383 //flush the remove upgradeFsmChan channel
1384 select {
1385 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001386 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001387 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001388 }
mpagenko59862f02021-10-11 08:53:18 +00001389 dh.lockUpgradeFsm.Unlock()
1390 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1391 dh.upgradeCanceled = true
1392 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1393 }
mpagenko38662d02021-08-11 09:45:19 +00001394 select {
1395 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001396 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001397 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1398 return
1399 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001401 }
mpagenko59862f02021-10-11 08:53:18 +00001402 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001403 }
mpagenko38662d02021-08-11 09:45:19 +00001404
1405 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001406 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001407 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001409 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001410 if err == nil {
1411 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1412 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1413 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001414 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001415 return
1416 }
mpagenko38662d02021-08-11 09:45:19 +00001417 } else {
1418 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001420 }
1421 return
1422 }
1423 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001424 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001425}
1426
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301427// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001428func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1429 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001430 var err error
1431 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1432 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1433 // 2.) activation of the inactive image
1434
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001435 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001436 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001437 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1438 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001439 }
1440 dh.lockUpgradeFsm.RLock()
1441 if dh.pOnuUpradeFsm != nil {
1442 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001443 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001444 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001445 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1446 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001447 }
mpagenko59862f02021-10-11 08:53:18 +00001448 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1449 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1450 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1451 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001452 // use the OnuVendor identification from this device for the internal unique name
1453 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001454 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001455 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001456 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001457 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001458 "device-id": dh.DeviceID, "error": err})
1459 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001460 }
mpagenko183647c2021-06-08 15:25:04 +00001461 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001463 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001464 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001465 } //else
1466 dh.lockUpgradeFsm.RUnlock()
1467
1468 // 2.) check if requested image-version equals the inactive one and start its activation
1469 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1470 var inactiveImageID uint16
1471 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1472 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1474 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001475 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001476 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001478 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 if err == nil {
1480 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1481 inactiveImageID, aCommitRequest); err != nil {
1482 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001483 "device-id": dh.DeviceID, "error": err})
1484 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001485 }
1486 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001487 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001488 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001489 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001490 } //else
1491 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001492 "device-id": dh.DeviceID, "error": err})
1493 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001494}
1495
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301496// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001497func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1498 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001499 var err error
1500 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1501 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1502 // 2.) commitment of the active image
1503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001504 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001506 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1507 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001508 }
1509 dh.lockUpgradeFsm.RLock()
1510 if dh.pOnuUpradeFsm != nil {
1511 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001512 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001513 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001514 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1515 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 }
mpagenko59862f02021-10-11 08:53:18 +00001517 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1518 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1519 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1520 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001521 // use the OnuVendor identification from this device for the internal unique name
1522 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001523 // 1.) check a started upgrade process and relay the commitment request to it
1524 // the running upgrade may be based either on the imageIdentifier (started from download)
1525 // or on the imageVersion (started from pure activation)
1526 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1527 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001528 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 "device-id": dh.DeviceID, "error": err})
1530 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001531 }
mpagenko183647c2021-06-08 15:25:04 +00001532 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001534 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001535 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001536 } //else
1537 dh.lockUpgradeFsm.RUnlock()
1538
mpagenko183647c2021-06-08 15:25:04 +00001539 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001540 var activeImageID uint16
1541 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1542 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001543 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1544 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001545 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001546 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001547 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001548 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001549 if err == nil {
1550 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1551 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001552 "device-id": dh.DeviceID, "error": err})
1553 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001554 }
1555 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001557 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001558 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001559 } //else
1560 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001561 "device-id": dh.DeviceID, "error": err})
1562 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001563}
1564
mpagenkoaa3afe92021-05-21 16:20:58 +00001565func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001566 aVersion string) *voltha.ImageState {
1567 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001568 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001569 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001570 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001571 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1572 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1573 if aVersion == dh.pLastUpgradeImageState.Version {
1574 pImageState = dh.pLastUpgradeImageState
1575 } else { //state request for an image version different from last processed image version
1576 pImageState = &voltha.ImageState{
1577 Version: aVersion,
1578 //we cannot state something concerning this version
1579 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1580 Reason: voltha.ImageState_NO_ERROR,
1581 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1582 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001583 }
1584 }
mpagenko38662d02021-08-11 09:45:19 +00001585 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001586}
1587
1588func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1589 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001591 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001592 dh.lockUpgradeFsm.RLock()
1593 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001594 dh.lockUpgradeFsm.RUnlock()
1595 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001596 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001597 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1598 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1599 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1600 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1601 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1602 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001603 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1604 dh.upgradeCanceled = true
1605 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1606 }
mpagenko45586762021-10-01 08:30:22 +00001607 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001608 } else {
mpagenko45586762021-10-01 08:30:22 +00001609 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001610 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1611 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1612 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1613 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1614 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1615 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001616 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1617 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001618 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1619 //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 +00001620 }
1621}
1622
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001623func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001626
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001628 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1630 pDevEntry.MutexOnuImageStatus.Lock()
1631 pDevEntry.POnuImageStatus = onuImageStatus
1632 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001633
1634 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001636 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1637 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1639 pDevEntry.MutexOnuImageStatus.Lock()
1640 pDevEntry.POnuImageStatus = nil
1641 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001642 return images, err
1643}
1644
Himani Chawla6d2ae152020-09-02 13:11:20 +05301645// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646// #####################################################################################
1647
1648// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301649// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001652 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1653 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654}
1655
1656// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001659 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660 var err error
1661
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662 // populate what we know. rest comes later after mib sync
1663 dh.device.Root = false
1664 dh.device.Vendor = "OpenONU"
1665 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001667 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001669 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001670
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001671 if !dh.IsReconciling() {
1672 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301673 if err = dh.updateDeviceInCore(ctx, dh.device); err != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -04001674 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1675 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301676 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001677 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301678 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001679 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001680 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681
Himani Chawla4d908332020-08-31 12:30:20 +05301682 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001683 dh.ponPortNumber = dh.device.ParentPortNo
1684
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1686 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1687 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001689 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301690 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691
1692 /*
1693 self._pon = PonPort.create(self, self._pon_port_number)
1694 self._pon.add_peer(self.parent_id, self._pon_port_number)
1695 self.logger.debug('adding-pon-port-to-agent',
1696 type=self._pon.get_port().type,
1697 admin_state=self._pon.get_port().admin_state,
1698 oper_status=self._pon.get_port().oper_status,
1699 )
1700 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001701 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301702 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001703 var ponPortNo uint32 = 1
1704 if dh.ponPortNumber != 0 {
1705 ponPortNo = dh.ponPortNumber
1706 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001708 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001709 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001710 PortNo: ponPortNo,
1711 Label: fmt.Sprintf("pon-%d", ponPortNo),
1712 Type: voltha.Port_PON_ONU,
1713 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301714 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001715 PortNo: ponPortNo}}, // Peer port is parent's port number
1716 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001718 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001719 e.Cancel(err)
1720 return
1721 }
1722 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301723 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001725 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726}
1727
1728// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001730
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001731 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001732 var err error
1733 /*
1734 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1735 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1736 return nil
1737 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001739 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740 e.Cancel(err)
1741 return
1742 }
1743
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001744 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001746 // reconcilement will be continued after mib download is done
1747 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001748
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001749 /*
1750 ############################################################################
1751 # Setup Alarm handler
1752 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1753 device.serial_number)
1754 ############################################################################
1755 # Setup PM configuration for this device
1756 # Pass in ONU specific options
1757 kwargs = {
1758 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1759 'heartbeat': self.heartbeat,
1760 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1761 }
1762 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1763 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1764 self.logical_device_id, device.serial_number,
1765 grouped=True, freq_override=False, **kwargs)
1766 pm_config = self._pm_metrics.make_proto()
1767 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1768 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1769 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1770
1771 # Note, ONU ID and UNI intf set in add_uni_port method
1772 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1773 ani_ports=[self._pon])
1774
1775 # Code to Run OMCI Test Action
1776 kwargs_omci_test_action = {
1777 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1778 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1779 }
1780 serial_number = device.serial_number
1781 self._test_request = OmciTestRequest(self.core_proxy,
1782 self.omci_agent, self.device_id,
1783 AniG, serial_number,
1784 self.logical_device_id,
1785 exclusive=False,
1786 **kwargs_omci_test_action)
1787
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001788 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 else:
1790 self.logger.info('onu-already-activated')
1791 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001792
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001793 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001794}
1795
1796// doStateConnected get the device info and update to voltha core
1797// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301798//
1799// voltha-openolt-adapter/adaptercore/device_handler.go
1800// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001803 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301804 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001806 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807}
1808
1809// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001812 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301813 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001815 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001816
1817 /*
1818 // Synchronous call to update device state - this method is run in its own go routine
1819 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1820 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001821 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 +00001822 return err
1823 }
1824 return nil
1825 */
1826}
1827
1828// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001830
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001831 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001832 var err error
1833
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001834 device := dh.device
1835 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001838 e.Cancel(err)
1839 return
1840 }
1841
1842 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001844 /*
1845 // Update the all ports state on that device to disable
1846 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001847 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001848 return er
1849 }
1850
1851 //Update the device oper state and connection status
1852 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1853 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1854 dh.device = cloned
1855
1856 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001857 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001858 return er
1859 }
1860
1861 //get the child device for the parent device
1862 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1863 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001864 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001865 return err
1866 }
1867 for _, onuDevice := range onuDevices.Items {
1868
1869 // Update onu state as down in onu adapter
1870 onuInd := oop.OnuIndication{}
1871 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001872 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001873 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1874 if er != nil {
1875 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001876 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001877 //Do not return here and continue to process other ONUs
1878 }
1879 }
1880 // * Discovered ONUs entries need to be cleared , since after OLT
1881 // is up, it starts sending discovery indications again* /
1882 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001883 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001884 return nil
1885 */
Himani Chawla4d908332020-08-31 12:30:20 +05301886 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001887 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001888 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001889}
1890
Himani Chawla6d2ae152020-09-02 13:11:20 +05301891// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001892// #################################################################################
1893
1894// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301895// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301897// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001898func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001899 dh.lockDevice.RLock()
1900 pOnuDeviceEntry := dh.pOnuOmciDevice
1901 if aWait && pOnuDeviceEntry == nil {
1902 //keep the read sema short to allow for subsequent write
1903 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001904 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001905 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1906 // so it might be needed to wait here for that event with some timeout
1907 select {
1908 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001909 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001910 return nil
1911 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001912 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001913 // if written now, we can return the written value without sema
1914 return dh.pOnuOmciDevice
1915 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001916 }
mpagenko3af1f032020-06-10 08:53:41 +00001917 dh.lockDevice.RUnlock()
1918 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001919}
1920
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301921// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1923 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001924 dh.lockDevice.Lock()
1925 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001926 dh.pOnuOmciDevice = apDeviceEntry
1927 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001928 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301929 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001930 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001931}
1932
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301933// addOnuDeviceEntry creates a new ONU device or returns the existing
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301934//
1935//nolint:unparam
Himani Chawla6d2ae152020-09-02 13:11:20 +05301936func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001940 if deviceEntry == nil {
1941 /* costum_me_map in python code seems always to be None,
1942 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1943 /* also no 'clock' argument - usage open ...*/
1944 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001945 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1946 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1947 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1948 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1949 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001950 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001952 // fire deviceEntry ready event to spread to possibly waiting processing
1953 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001954 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001955 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001957 }
1958 // might be updated with some error handling !!!
1959 return nil
1960}
1961
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001963 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001964 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1965
1966 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001967
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001969 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001970 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1971 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001972 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05301973
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 if !dh.IsReconciling() {
1975 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001977 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001978 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001980 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001981
khenaidoo42dcdfd2021-10-19 17:34:12 -04001982 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001984 OperStatus: voltha.OperStatus_ACTIVATING,
1985 ConnStatus: voltha.ConnectStatus_REACHABLE,
1986 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001987 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001989 }
1990 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301991 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001993
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001994 pDevEntry.MutexPersOnuConfig.RLock()
1995 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1996 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 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 +00001998 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001999 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302000
2001 //VOL-4965: Recover previously Activating ONU during reconciliation.
2002 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2003 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2004 log.Fields{"device-id": dh.DeviceID})
2005 pDevEntry.MutexPersOnuConfig.Lock()
2006 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2007 pDevEntry.MutexPersOnuConfig.Unlock()
2008 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002009 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002011 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002012 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002013 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2014 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2015 // 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 +00002016 // 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 +00002017 // so let's just try to keep it simple ...
2018 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002020 if err != nil || device == nil {
2021 //TODO: needs to handle error scenarios
2022 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2023 return errors.New("Voltha Device not found")
2024 }
2025 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002026
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002027 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002028 return err
mpagenko3af1f032020-06-10 08:53:41 +00002029 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002030 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302031 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2032 /* this might be a good time for Omci Verify message? */
2033 verifyExec := make(chan bool)
2034 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2035 dh.device.Id, pDevEntry.PDevOmciCC, false,
2036 true, true) //exclusive and allowFailure (anyway not yet checked)
2037 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302039 /* give the handler some time here to wait for the OMCi verification result
2040 after Timeout start and try MibUpload FSM anyway
2041 (to prevent stopping on just not supported OMCI verification from ONU) */
2042 select {
2043 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2044 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2045 case testresult := <-verifyExec:
2046 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2047 case <-dh.deviceDeleteCommChan:
2048 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2049 return nil
2050 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002051 }
2052
2053 /* In py code it looks earlier (on activate ..)
2054 # Code to Run OMCI Test Action
2055 kwargs_omci_test_action = {
2056 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2057 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2058 }
2059 serial_number = device.serial_number
2060 self._test_request = OmciTestRequest(self.core_proxy,
2061 self.omci_agent, self.device_id,
2062 AniG, serial_number,
2063 self.logical_device_id,
2064 exclusive=False,
2065 **kwargs_omci_test_action)
2066 ...
2067 # Start test requests after a brief pause
2068 if not self._test_request_started:
2069 self._test_request_started = True
2070 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2071 reactor.callLater(tststart, self._test_request.start_collector)
2072
2073 */
2074 /* which is then: in omci_test_request.py : */
2075 /*
2076 def start_collector(self, callback=None):
2077 """
2078 Start the collection loop for an adapter if the frequency > 0
2079
2080 :param callback: (callable) Function to call to collect PM data
2081 """
2082 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2083 if callback is None:
2084 callback = self.perform_test_omci
2085
2086 if self.lc is None:
2087 self.lc = LoopingCall(callback)
2088
2089 if self.default_freq > 0:
2090 self.lc.start(interval=self.default_freq / 10)
2091
2092 def perform_test_omci(self):
2093 """
2094 Perform the initial test request
2095 """
2096 ani_g_entities = self._device.configuration.ani_g_entities
2097 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2098 is not None else None
2099 self._entity_id = ani_g_entities_ids[0]
2100 self.logger.info('perform-test', entity_class=self._entity_class,
2101 entity_id=self._entity_id)
2102 try:
2103 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2104 result = yield self._device.omci_cc.send(frame)
2105 if not result.fields['omci_message'].fields['success_code']:
2106 self.logger.info('Self-Test Submitted Successfully',
2107 code=result.fields[
2108 'omci_message'].fields['success_code'])
2109 else:
2110 raise TestFailure('Test Failure: {}'.format(
2111 result.fields['omci_message'].fields['success_code']))
2112 except TimeoutError as e:
2113 self.deferred.errback(failure.Failure(e))
2114
2115 except Exception as e:
2116 self.logger.exception('perform-test-Error', e=e,
2117 class_id=self._entity_class,
2118 entity_id=self._entity_id)
2119 self.deferred.errback(failure.Failure(e))
2120
2121 */
2122
2123 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002124 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002125
mpagenko1cc3cb42020-07-27 15:24:38 +00002126 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2127 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2128 * 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 +05302129 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002130 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002131 //call MibUploadFSM - transition up to state UlStInSync
2132 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002133 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002134 if pMibUlFsm.Is(mib.UlStDisabled) {
2135 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2136 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2137 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302138 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002139 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302140 //Determine ONU status and start/re-start MIB Synchronization tasks
2141 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002142 if pDevEntry.IsNewOnu() {
2143 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2144 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2145 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002146 }
Himani Chawla4d908332020-08-31 12:30:20 +05302147 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002148 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2149 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2150 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302151 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002152 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002153 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002154 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002155 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002156 "device-id": dh.DeviceID})
2157 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002158 }
2159 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2161 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002162 }
2163 return nil
2164}
2165
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002166func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002167 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002168 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002169 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302170 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002171
mpagenko900ee4b2020-10-12 11:56:34 +00002172 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2173 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2174 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002175 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002177 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002178 // abort: system behavior is just unstable ...
2179 return err
2180 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002181 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 _ = dh.deleteDevicePersistencyData(ctx) //ignore possible errors here and continue, hope is that data is synchronized with new ONU-Up
mpagenko900ee4b2020-10-12 11:56:34 +00002183
2184 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002185 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002186 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002187 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002188 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2189 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002190 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002192
2193 //TODO!!! remove existing traffic profiles
2194 /* from py code, if TP's exist, remove them - not yet implemented
2195 self._tp = dict()
2196 # Let TP download happen again
2197 for uni_id in self._tp_service_specific_task:
2198 self._tp_service_specific_task[uni_id].clear()
2199 for uni_id in self._tech_profile_download_done:
2200 self._tech_profile_download_done[uni_id].clear()
2201 */
2202
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002203 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002204
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002206
mpagenkoe4782082021-11-25 12:04:26 +00002207 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002208 // abort: system behavior is just unstable ...
2209 return err
2210 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002213 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002214 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002215 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2216 OperStatus: voltha.OperStatus_DISCOVERED,
2217 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002218 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002220 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002221 // abort: system behavior is just unstable ...
2222 return err
2223 }
2224 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002226 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002227 return nil
2228}
2229
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002230func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002231 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2232 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2233 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2234 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002235 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002236
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302238 //VOL-5260: During race conditions when adoptDevice has not yet completed
2239 // and deleteDevice is issued , returning error will further prevent clean up
2240 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002241 if pDevEntry == nil {
mgoudaa797e1c2025-06-24 17:49:42 +05302242 errMsg := fmt.Sprintf("Device entry is not found %s", dh.DeviceID)
2243 logger.Error(ctx, errMsg)
2244 return status.Error(codes.NotFound, errMsg)
mpagenko900ee4b2020-10-12 11:56:34 +00002245 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002246 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002247 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002248 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002249 pDevEntry.MutexOnuImageStatus.RLock()
2250 if pDevEntry.POnuImageStatus != nil {
2251 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002252 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002254
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002255 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002256 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002257 }
2258 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002259 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002260 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002261 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002262 }
mpagenko101ac942021-11-16 15:01:29 +00002263 //stop any deviceHandler reconcile processing (if running)
2264 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002265 //port lock/unlock FSM's may be active
2266 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002267 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002268 }
2269 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002271 }
2272 //techProfile related PonAniConfigFsm FSM may be active
2273 if dh.pOnuTP != nil {
2274 // should always be the case here
2275 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002276 if dh.pOnuTP.PAniConfigFsm != nil {
2277 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2278 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002279 }
mpagenko900ee4b2020-10-12 11:56:34 +00002280 }
2281 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002282 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002283 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002285 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002286 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002287 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002288 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002289 } else {
2290 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002291 }
2292 }
2293 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302294
2295 dh.mutexCollectorFlag.Lock()
2296 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2297 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002298 // Stop collector routine
2299 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302300 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002301 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302302 dh.mutexCollectorFlag.Unlock()
2303
2304 dh.mutextAlarmManagerFlag.Lock()
2305 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2306 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302307 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302308 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302309 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302310 dh.mutextAlarmManagerFlag.Unlock()
2311
2312 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2313 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2314 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002315 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302316 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002317 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302318 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302319
Girish Gowdrae95687a2021-09-08 16:30:58 -07002320 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2321
mpagenko80622a52021-02-09 16:53:23 +00002322 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002323 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002324 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002325 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002327 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002328 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002329 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2330 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2331 // (even though it may also run into direct cancellation, a bit hard to verify here)
2332 // so don't set 'dh.upgradeCanceled = true' here!
2333 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2334 }
mpagenko38662d02021-08-11 09:45:19 +00002335 }
mpagenko80622a52021-02-09 16:53:23 +00002336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002337 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002338 return nil
2339}
2340
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302341//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2343 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 +05302344
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002345 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002346 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002347 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002349 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002350 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002352
mpagenkoa40e99a2020-11-17 13:50:39 +00002353 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2354 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2355 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2356 * disable/enable toggling here to allow traffic
2357 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2358 * like the py comment says:
2359 * # start by locking all the unis till mib sync and initial mib is downloaded
2360 * # this way we can capture the port down/up events when we are ready
2361 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302362
mpagenkoa40e99a2020-11-17 13:50:39 +00002363 // Init Uni Ports to Admin locked state
2364 // *** should generate UniLockStateDone event *****
2365 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002366 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002367 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002369 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002370 }
2371}
2372
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302373//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2375 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 /* Mib download procedure -
2377 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2378 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002380 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002381 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002382 return
2383 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302385 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 if pMibDlFsm.Is(mib.DlStDisabled) {
2387 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2388 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 +05302389 // maybe try a FSM reset and then again ... - TODO!!!
2390 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002391 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302392 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2394 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302395 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002396 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302397 //Begin MIB data download (running autonomously)
2398 }
2399 }
2400 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002401 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002402 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302403 // maybe try a FSM reset and then again ... - TODO!!!
2404 }
2405 /***** Mib download started */
2406 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002407 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302408 }
2409}
2410
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302411//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302413 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002414 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2415 if pDevEntry == nil {
2416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2417 return
2418 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002420 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002421 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002422 // update device info in core
2423 pDevEntry.MutexPersOnuConfig.RLock()
2424 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2425 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2426 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2427 pDevEntry.MutexPersOnuConfig.RUnlock()
2428 dh.logicalDeviceID = dh.DeviceID
2429 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2430 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2431 }
2432 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002433 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2434 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2435 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2436 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002437 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002439 ConnStatus: voltha.ConnectStatus_REACHABLE,
2440 OperStatus: voltha.OperStatus_ACTIVE,
2441 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302442 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302444 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002445 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302446 }
2447 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302448 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302450 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002451 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002454 var waitForOmciProcessor sync.WaitGroup
2455 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002456 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002457 go dh.StartCollector(ctx, &waitForOmciProcessor)
2458 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002459 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 if !dh.GetAlarmManagerIsRunning(ctx) {
2461 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002462 }
2463
Girish Gowdrae95687a2021-09-08 16:30:58 -07002464 // Start flow handler routines per UNI
2465 for _, uniPort := range dh.uniEntityMap {
2466 // only if this port was enabled for use by the operator at startup
2467 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2468 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2469 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2470 }
2471 }
2472 }
2473
Girish Gowdrae0140f02021-02-02 16:55:09 -08002474 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002476 // There is no way we should be landing here, but if we do then
2477 // there is nothing much we can do about this other than log error
2478 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2479 }
2480
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002482
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 pDevEntry.MutexPersOnuConfig.RLock()
2484 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2485 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302486 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002488 dh.mutexForDisableDeviceRequested.Lock()
2489 dh.disableDeviceRequested = true
2490 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002491 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002492 // reconcilement will be continued after ani config is done
2493 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002495 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002496 dh.mutexForDisableDeviceRequested.RLock()
2497 if !dh.disableDeviceRequested {
2498 if dh.pUnlockStateFsm == nil {
2499 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2500 } else { //UnlockStateFSM already init
2501 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2502 dh.runUniLockFsm(ctx, false)
2503 }
2504 dh.mutexForDisableDeviceRequested.RUnlock()
2505 } else {
2506 dh.mutexForDisableDeviceRequested.RUnlock()
2507 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002508 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302509 }
2510}
2511
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302512//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002513func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2514 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002516 if !dh.IsReconciling() {
2517 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002518 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2520 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002521 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002523 return
2524 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 pDevEntry.MutexPersOnuConfig.Lock()
2526 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2527 pDevEntry.MutexPersOnuConfig.Unlock()
2528 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002531 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302532 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302533 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 +00002534 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002535 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302536
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002537 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302538
Himani Chawla26e555c2020-08-31 12:30:20 +05302539 }
2540}
2541
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302542//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002544 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002546
mpagenko44bd8362021-11-15 11:40:05 +00002547 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002548 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002549 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002550 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002551 OperStatus: voltha.OperStatus_UNKNOWN,
2552 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002553 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002555 }
2556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002558 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002559 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002560
2561 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002563
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002565 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002566 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002567 return
2568 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 pDevEntry.MutexPersOnuConfig.Lock()
2570 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2571 pDevEntry.MutexPersOnuConfig.Unlock()
2572 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002575 }
mpagenko900ee4b2020-10-12 11:56:34 +00002576}
2577
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302578//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002580 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002582 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002583 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002584 ConnStatus: voltha.ConnectStatus_REACHABLE,
2585 OperStatus: voltha.OperStatus_ACTIVE,
2586 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002587 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002589 }
2590
dbainbri4d3a0dc2020-12-02 00:33:42 +00002591 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002593 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002594 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002595
2596 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002600 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002602 return
2603 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 pDevEntry.MutexPersOnuConfig.Lock()
2605 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2606 pDevEntry.MutexPersOnuConfig.Unlock()
2607 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002610 }
mpagenko900ee4b2020-10-12 11:56:34 +00002611}
2612
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302613//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002614func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2615 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2616 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002617 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002618 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002619 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002620 OperStatus: voltha.OperStatus_FAILED,
2621 }); err != nil {
2622 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2623 }
2624}
2625
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002626func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2627 if devEvent == cmn.OmciAniConfigDone {
2628 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002629 // attention: the device reason update is done based on ONU-UNI-Port related activity
2630 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002632 // 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 +00002633 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302634 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002635 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002636 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2637 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2638 dh.mutexReconcilingFirstPassFlag.Lock()
2639 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302640 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002641 dh.reconcilingFirstPass = false
2642 go dh.ReconcileDeviceFlowConfig(ctx)
2643 }
2644 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002645 }
2646 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002647 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002648 // attention: the device reason update is done based on ONU-UNI-Port related activity
2649 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002651 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2652 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002653 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002654 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302655}
2656
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002658 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302660 // attention: the device reason update is done based on ONU-UNI-Port related activity
2661 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302662
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2664 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002665 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002666 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002667 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002668 }
2669 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002670 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002671 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002672 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002673 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302674 }
mpagenkof1fc3862021-02-16 10:09:52 +00002675
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002676 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002677 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002679 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002681 }
2682 } else {
2683 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002684 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002685 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302686}
2687
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302688// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302690 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002692 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002693 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002694 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002696 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002698 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002699 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002700 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002701 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002702 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002704 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002705 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002706 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002708 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002709 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002710 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002711 case cmn.UniEnableStateFailed:
2712 {
2713 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2714 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002716 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002717 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002718 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002720 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002722 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002724 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002725 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002726 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002727 default:
2728 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002729 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002730 }
2731 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002732}
2733
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002735 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002736 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302737 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002738 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002739 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002740 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302741 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002743 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002744 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 +00002745 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002746 //store UniPort with the System-PortNumber key
2747 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002749 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002751 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002752 } //error logging already within UniPort method
2753 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302754 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002755 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002756 }
2757 }
2758}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002759
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2761 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002762 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002764 return
2765 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002766 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002768 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2769 for _, mgmtEntityID := range pptpInstKeys {
2770 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002771 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002772 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2773 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002774 }
2775 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002776 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002777 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002778 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002779 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2780 for _, mgmtEntityID := range veipInstKeys {
2781 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002783 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2784 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002785 }
2786 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002788 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002790 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2791 for _, mgmtEntityID := range potsInstKeys {
2792 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002794 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2795 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002796 }
2797 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002799 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002800 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002802 return
2803 }
2804
mpagenko2c3f6c52021-11-23 11:22:10 +00002805 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2806 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2807 // 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 -07002808 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2809 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2810 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002811 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2812 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002813 for i := 0; i < int(uniCnt); i++ {
2814 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002815 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002816 }
2817}
2818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2820func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002821 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302822 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002823 // with following remark:
2824 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2825 // # load on the core
2826
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002827 // 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 +00002828
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002829 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002830 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002831 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2832 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2833 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2834 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002835 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002836 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002837 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002838 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002839 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002840 PortNo: port.PortNo,
2841 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002842 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002843 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 -04002844 }
2845 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002846 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302847 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002848 }
mpagenko3af1f032020-06-10 08:53:41 +00002849 }
2850 }
2851}
2852
2853// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2855 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002856 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2857 for uniNo, uniPort := range dh.uniEntityMap {
2858 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002859
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002860 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2861 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2862 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2863 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002864 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002866 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002867 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002868 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 PortNo: port.PortNo,
2870 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002871 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002872 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 -04002873 }
2874 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002875 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302876 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002877 }
2878
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002879 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002880 }
2881}
2882
2883// ONU_Active/Inactive announcement on system KAFKA bus
2884// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002885func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002886 var de voltha.DeviceEvent
2887 eventContext := make(map[string]string)
2888 //Populating event context
2889 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002890 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002891 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002892 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002893 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002894 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 +00002895 }
2896 oltSerialNumber := parentDevice.SerialNumber
2897
2898 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2899 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2900 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302901 eventContext["olt-serial-number"] = oltSerialNumber
2902 eventContext["device-id"] = aDeviceID
2903 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002904 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2906 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002907 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2908 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2910 deviceEntry.MutexPersOnuConfig.RUnlock()
2911 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002913 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2914 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2915 } else {
2916 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2917 log.Fields{"device-id": aDeviceID})
2918 return
2919 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002920
2921 /* Populating device event body */
2922 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302923 de.ResourceId = aDeviceID
2924 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002925 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2926 de.Description = fmt.Sprintf("%s Event - %s - %s",
2927 cEventObjectType, cOnuActivatedEvent, "Raised")
2928 } else {
2929 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2930 de.Description = fmt.Sprintf("%s Event - %s - %s",
2931 cEventObjectType, cOnuActivatedEvent, "Cleared")
2932 }
2933 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302934 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002935 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302936 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002937 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302938 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302939 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002940}
2941
Himani Chawla4d908332020-08-31 12:30:20 +05302942// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05302944 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002945 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302946 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002948 sFsmName = "LockStateFSM"
2949 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002951 sFsmName = "UnLockStateFSM"
2952 }
mpagenko3af1f032020-06-10 08:53:41 +00002953
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002955 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002957 return
2958 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002960 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302961 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002962 dh.pLockStateFsm = pLSFsm
2963 } else {
2964 dh.pUnlockStateFsm = pLSFsm
2965 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002966 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002967 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002969 }
2970}
2971
2972// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002973func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002974 /* Uni Port lock/unlock procedure -
2975 ***** should run via 'adminDone' state and generate the argument requested event *****
2976 */
2977 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302978 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002980 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2981 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002982 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2983 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002984 }
2985 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002987 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2988 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2990 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002991 }
2992 }
2993 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2995 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002996 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002997 // maybe try a FSM reset and then again ... - TODO!!!
2998 } else {
2999 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003000 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003002 }
3003 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003006 // maybe try a FSM reset and then again ... - TODO!!!
3007 }
3008 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003010 // maybe try a FSM reset and then again ... - TODO!!!
3011 }
3012}
3013
mpagenko80622a52021-02-09 16:53:23 +00003014// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003015// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303016//
3017//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003018func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303019 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003020 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003022 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003023 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303024 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003025 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003026 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003027 sFsmName, chUpgradeFsm)
3028 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003029 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003030 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3032 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003033 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003034 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303035 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003036 }
mpagenko59862f02021-10-11 08:53:18 +00003037 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003038 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3039 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003040 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3041 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003042 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003044 } else {
3045 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003047 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303048 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003049 }
3050 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003051 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003052 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303053 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003054 }
3055 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303057 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003058 }
3059 return nil
3060}
3061
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3063func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003064 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003066 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003067 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3068 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003069 dh.pLastUpgradeImageState = apImageState
3070 dh.lockUpgradeFsm.Unlock()
3071 //signal upgradeFsm removed using non-blocking channel send
3072 select {
3073 case dh.upgradeFsmChan <- struct{}{}:
3074 default:
3075 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003076 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003077 }
mpagenko80622a52021-02-09 16:53:23 +00003078}
3079
mpagenko15ff4a52021-03-02 10:09:20 +00003080// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3081func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003082 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003083 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003085 return
3086 }
3087
3088 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003089 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003090 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003091 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3092 dh.lockUpgradeFsm.RUnlock()
3093 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3094 return
3095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003096 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003097 if pUpgradeStatemachine != nil {
3098 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3099 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003100 UpgradeState := pUpgradeStatemachine.Current()
3101 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3102 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3103 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003104 // 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 +00003105 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003106 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3107 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003108 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003109 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003110 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003111 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3112 dh.upgradeCanceled = true
3113 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3114 }
mpagenko15ff4a52021-03-02 10:09:20 +00003115 return
3116 }
mpagenko59862f02021-10-11 08:53:18 +00003117 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3119 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003120 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003122 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3123 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003124 return
3125 }
3126 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003127 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003128 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3130 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003131 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3132 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003133 return
3134 }
3135 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003137 }
3138 } else {
3139 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 +00003140 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003141 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3142 dh.upgradeCanceled = true
3143 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3144 }
mpagenko1f8e8822021-06-25 14:10:21 +00003145 }
mpagenko15ff4a52021-03-02 10:09:20 +00003146 return
3147 }
mpagenko59862f02021-10-11 08:53:18 +00003148 dh.lockUpgradeFsm.RUnlock()
3149 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3150 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003151 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3152 dh.upgradeCanceled = true
3153 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3154 }
mpagenko59862f02021-10-11 08:53:18 +00003155 return
3156 }
3157 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3158 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3159 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3160 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3161 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3162 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3163 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003164 }
mpagenko15ff4a52021-03-02 10:09:20 +00003165 }
3166 }
3167 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003169 }
mpagenko59862f02021-10-11 08:53:18 +00003170 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003171}
3172
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303173// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003175
3176 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003177 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003178 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003179 kvbackend := &db.Backend{
3180 Client: dh.pOpenOnuAc.kvClient,
3181 StoreType: dh.pOpenOnuAc.KVStoreType,
3182 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003183 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003184 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3185 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003186
mpagenkoaf801632020-07-03 10:00:42 +00003187 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003188}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303189
3190//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003191func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303192 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003193
mpagenkodff5dda2020-08-28 11:52:01 +00003194 for _, field := range flow.GetOfbFields(apFlowItem) {
3195 switch field.Type {
3196 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3197 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003199 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3200 }
mpagenko01e726e2020-10-23 09:45:29 +00003201 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003202 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3203 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303204 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003205 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303206 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3207 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003208 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3209 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003210 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003211 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303212 return
mpagenkodff5dda2020-08-28 11:52:01 +00003213 }
3214 }
mpagenko01e726e2020-10-23 09:45:29 +00003215 */
mpagenkodff5dda2020-08-28 11:52:01 +00003216 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3217 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303218 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003219 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303220 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003221 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303222 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003223 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003224 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303225 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003226 }
3227 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3228 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303229 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003230 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303231 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003232 }
3233 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3234 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003236 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3237 }
3238 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3239 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003240 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003241 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3242 }
3243 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3244 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003245 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003246 "IPv4-DST": field.GetIpv4Dst()})
3247 }
3248 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3249 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003250 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003251 "IPv4-SRC": field.GetIpv4Src()})
3252 }
3253 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3254 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003255 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003256 "Metadata": field.GetTableMetadata()})
3257 }
3258 /*
3259 default:
3260 {
3261 //all other entires ignored
3262 }
3263 */
3264 }
3265 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303266}
mpagenkodff5dda2020-08-28 11:52:01 +00003267
khenaidoo7d3c5582021-08-11 18:09:44 -04003268func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003269 for _, action := range flow.GetActions(apFlowItem) {
3270 switch action.Type {
3271 /* not used:
3272 case of.OfpActionType_OFPAT_OUTPUT:
3273 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003274 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003275 "Output": action.GetOutput()})
3276 }
3277 */
3278 case of.OfpActionType_OFPAT_PUSH_VLAN:
3279 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003280 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003281 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3282 }
3283 case of.OfpActionType_OFPAT_SET_FIELD:
3284 {
3285 pActionSetField := action.GetSetField()
3286 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003287 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003288 "OxcmClass": pActionSetField.Field.OxmClass})
3289 }
3290 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303291 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003292 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303293 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003294 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303295 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003296 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303297 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003298 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003299 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003300 "Type": pActionSetField.Field.GetOfbField().Type})
3301 }
3302 }
3303 /*
3304 default:
3305 {
3306 //all other entires ignored
3307 }
3308 */
3309 }
3310 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303311}
3312
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303313// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003314func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003315 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303316 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3317 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303318 var loSetPcp uint8
3319 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303320 var loIPProto uint32
3321 /* the TechProfileId is part of the flow Metadata - compare also comment within
3322 * OLT-Adapter:openolt_flowmgr.go
3323 * Metadata 8 bytes:
3324 * Most Significant 2 Bytes = Inner VLAN
3325 * Next 2 Bytes = Tech Profile ID(TPID)
3326 * Least Significant 4 Bytes = Port ID
3327 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3328 * subscriber related flows.
3329 */
3330
dbainbri4d3a0dc2020-12-02 00:33:42 +00003331 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303332 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003333 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003334 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003335 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303336 }
mpagenko551a4d42020-12-08 18:09:20 +00003337 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003338 loCookie := apFlowItem.GetCookie()
3339 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303340 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303342 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303343
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303344 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003345 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303346 if loIPProto == 2 {
3347 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3348 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003349 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003350 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303351 return nil
3352 }
mpagenko01e726e2020-10-23 09:45:29 +00003353 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003354 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003355
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303356 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3357 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003358 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003360 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3361 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3362 //TODO!!: Use DeviceId within the error response to rwCore
3363 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003364 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003365 }
3366 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003367 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003368 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303369 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3370 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3371 loSetVlan = loMatchVlan
3372 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 +00003373 } else {
3374 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3375 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3376 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303377 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003379 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003380 }
mpagenko9a304ea2020-12-16 15:54:01 +00003381
khenaidoo42dcdfd2021-10-19 17:34:12 -04003382 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003383 if apFlowMetaData != nil {
3384 meter = apFlowMetaData.Meters[0]
3385 }
mpagenkobc4170a2021-08-17 16:42:10 +00003386 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3387 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3388 // when different rules are requested concurrently for the same uni
3389 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3390 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3391 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3393 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003394 //SetUniFlowParams() may block on some rule that is suspended-to-add
3395 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003396 // Also the error is returned to caller via response channel
3397 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303398 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003399 dh.lockVlanConfig.RUnlock()
3400 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003401 return
mpagenkodff5dda2020-08-28 11:52:01 +00003402 }
mpagenkobc4170a2021-08-17 16:42:10 +00003403 dh.lockVlanConfig.RUnlock()
3404 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003405 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303406 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003407 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003408 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003409 if err != nil {
3410 *respChan <- err
3411 }
mpagenko01e726e2020-10-23 09:45:29 +00003412}
3413
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303414// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003415func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003416 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3417 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3418 //no extra check is done on the rule parameters
3419 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3420 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3421 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3422 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003423 // - 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 +00003424 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003426
3427 /* TT related temporary workaround - should not be needed anymore
3428 for _, field := range flow.GetOfbFields(apFlowItem) {
3429 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3430 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003432 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3433 if loIPProto == 2 {
3434 // 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 +00003435 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003436 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003437 return nil
3438 }
3439 }
3440 } //for all OfbFields
3441 */
3442
mpagenko9a304ea2020-12-16 15:54:01 +00003443 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003444 dh.lockVlanConfig.RLock()
3445 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3447 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003448 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3449 return
mpagenko01e726e2020-10-23 09:45:29 +00003450 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003451 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003453 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003454 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003455 // Push response on the response channel
3456 if respChan != nil {
3457 // 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
3458 select {
3459 case *respChan <- nil:
3460 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3461 default:
3462 }
3463 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003464 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003465}
3466
Himani Chawla26e555c2020-08-31 12:30:20 +05303467// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003468// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003469// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003470func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303471 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303472 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003473
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003475 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3477 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003478 }
3479
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303480 if dh.pDeviceStateFsm.Current() == devStDown {
3481 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3482 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3483 }
3484
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003485 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3486 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303487 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003488 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003489 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3490 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003491 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3492 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003493 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3495 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003496 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3497 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003498 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003499 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303500 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003501 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3503 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003504 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003505 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3507 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003508 }
3509 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003510 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003511 "device-id": dh.DeviceID})
3512 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003513 }
3514 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003515 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3517 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003518 }
3519 return nil
3520}
3521
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303522// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003523// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003524func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003525 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003527 for _, uniPort := range dh.uniEntityMap {
3528 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003530 pCurrentUniPort = uniPort
3531 break //found - end search loop
3532 }
3533 }
3534 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003535 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003537 return
3538 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003540}
3541
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303542// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003543func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003544 //TODO!! verify and start pending flow configuration
3545 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3546 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303547 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003548 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003549 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003550 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003551 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003553 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003554 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003555 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003556 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3557 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003558 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003559 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003560 } else {
3561 /***** UniVlanConfigFsm continued */
3562 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003563 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3564 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003565 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003566 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3567 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003568 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003569 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003570 } else {
3571 /***** UniVlanConfigFsm continued */
3572 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3574 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003575 }
mpagenkodff5dda2020-08-28 11:52:01 +00003576 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003577 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3579 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003580 }
3581 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003582 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 +00003583 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3584 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003585 }
3586 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003587 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003588 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003589 }
mpagenkof1fc3862021-02-16 10:09:52 +00003590 } else {
3591 dh.lockVlanConfig.RUnlock()
3592 }
mpagenkodff5dda2020-08-28 11:52:01 +00003593}
3594
Akash Soni3de0e062024-12-11 16:37:26 +05303595// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3596func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3597 dh.lockVlanConfig.Lock()
3598 defer dh.lockVlanConfig.Unlock()
3599
3600 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3601 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3602 if pVlanFilterStatemachine != nil {
3603 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3604 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3605 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3606 })
3607 } else {
3608 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3609 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3610 })
3611 }
3612 } else {
3613 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3614 "device-id": dh.DeviceID, "UniPort": uniID,
3615 })
3616 }
3617 } else {
3618 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3619 "device-id": dh.DeviceID, "UniPort": uniID,
3620 })
3621 }
3622}
3623
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303624// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003625// 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 +00003626func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003627 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003629 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003630 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003632 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003633}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003634
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303635// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003636func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003637 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3638 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3639 // obviously then parallel processing on the cancel must be avoided
3640 // deadline context to ensure completion of background routines waited for
3641 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3642 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3643 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303644 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003645
Akash Soni840f8d62024-12-11 19:37:06 +05303646 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3647 if err != nil {
3648 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3649 return err
3650 }
3651 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003652}
3653
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303654// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3655// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003656func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3657 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003659 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303660 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003661 return nil
3662 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003663 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003666 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003667 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3668 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003669 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003670 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003671
mpagenkof1fc3862021-02-16 10:09:52 +00003672 if aWriteToKvStore {
3673 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3674 }
3675 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003676}
3677
dbainbri4d3a0dc2020-12-02 00:33:42 +00003678func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003679 defer cancel() //ensure termination of context (may be pro forma)
3680 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003681 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003682 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003683}
3684
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303685// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3686//
3687// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003688func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3689 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3690 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3691 dh.mutexDeviceReason.Lock()
3692 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003693 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003694 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003695 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 DeviceId: dh.DeviceID,
3697 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003698 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003699 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003701 return err
3702 }
mpagenkoe4782082021-11-25 12:04:26 +00003703 } else {
3704 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 +00003705 }
mpagenkoe4782082021-11-25 12:04:26 +00003706 dh.deviceReason = deviceReason
3707 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3708 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003709 return nil
3710}
3711
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003712func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3713 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003714 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003715 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3716 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003717 }
mpagenkof1fc3862021-02-16 10:09:52 +00003718 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003719}
3720
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003721// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003722// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003723func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3724 dh.lockDevice.RLock()
3725 defer dh.lockDevice.RUnlock()
3726 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003727 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003728 }
3729 return 0, errors.New("error-fetching-uni-port")
3730}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003731
3732// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003733func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3734 var errorsList []error
3735 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 -08003736
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003737 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3738 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3739 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3740
3741 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3742 // successfully.
3743 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3744 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3745 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003746 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 -08003747 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003748 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003749 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003750 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003751}
3752
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003753func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3754 var err error
3755 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003756 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003757
3758 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003760 errorsList = append(errorsList, err)
3761 }
3762 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003763 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003764
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003765 return errorsList
3766}
3767
3768func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3769 var err error
3770 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003771 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003772 // Check if group metric related config is updated
3773 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003774 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3775 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3776 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778 if ok && m.Frequency != v.GroupFreq {
3779 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003780 errorsList = append(errorsList, err)
3781 }
3782 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003783 if ok && m.Enabled != v.Enabled {
3784 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003785 errorsList = append(errorsList, err)
3786 }
3787 }
3788 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003789 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003790 return errorsList
3791}
3792
3793func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3794 var err error
3795 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003796 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003797 // Check if standalone metric related config is updated
3798 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003799 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3800 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3801 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003802
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803 if ok && m.Frequency != v.SampleFreq {
3804 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003805 errorsList = append(errorsList, err)
3806 }
3807 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808 if ok && m.Enabled != v.Enabled {
3809 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003810 errorsList = append(errorsList, err)
3811 }
3812 }
3813 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003814 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003815 return errorsList
3816}
3817
3818// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003819func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003820 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003821
3822 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003823 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303824 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003825 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003826 // Initialize the next metric collection time.
3827 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3828 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003830 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303831 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3832 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003833 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303834
Girish Gowdrae09a6202021-01-12 18:10:59 -08003835 select {
3836 case <-dh.stopCollector:
3837 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003838 // Stop the L2 PM FSM
3839 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003840 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3841 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3842 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003843 }
3844 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003846 }
3847 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003848 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3849 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003850 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003851 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3852 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003853 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003854
Girish Gowdrae09a6202021-01-12 18:10:59 -08003855 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303856 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003857 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3858 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3859 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3860 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003861 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003862 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
3863 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003864 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003865 } else {
3866 if dh.pmConfigs.Grouped { // metrics are managed as a group
3867 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3871 // 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 -08003872 // 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 +00003873 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3874 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003875 }
3876 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003877 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3878 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3879 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3880 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003881 }
3882 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003883 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003884
3885 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003886 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3887 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3888 // 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 -08003889 // 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 +00003890 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003891 prevInternal := g.NextCollectionInterval
3892 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003893 }
3894 }
3895 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003896 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3897 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3898 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003899 prevInternal := m.NextCollectionInterval
3900 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003901 }
3902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003904 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003905 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003906 } */
3907 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003908 }
3909 }
3910}
kesavandfdf77632021-01-26 23:40:33 -05003911
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303912//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05303913func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
3914
3915 singleValResp := extension.SingleSetValueResponse{
3916 Response: &extension.SetValueResponse{
3917 Status: extension.SetValueResponse_OK,
3918 },
3919 }
3920
3921 return &singleValResp
3922}
3923
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003924func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003926 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3927 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003928}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003929
Himani Chawla43f95ff2021-06-03 00:24:12 +05303930func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3931 if dh.pOnuMetricsMgr == nil {
3932 return &extension.SingleGetValueResponse{
3933 Response: &extension.GetValueResponse{
3934 Status: extension.GetValueResponse_ERROR,
3935 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3936 },
3937 }
3938 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303939 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303940 return resp
3941}
3942
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003943func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3944
3945 var err error
3946 var pDevOmciCC *cmn.OmciCC
3947 if dh.pOnuOmciDevice == nil {
3948 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3949 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3950 } else {
3951 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3952 if pDevOmciCC == nil {
3953 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3954 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3955 }
3956 }
3957 if err != nil {
3958 return &extension.SingleGetValueResponse{
3959 Response: &extension.GetValueResponse{
3960 Status: extension.GetValueResponse_ERROR,
3961 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3962 },
3963 },
3964 err
3965 }
3966 return pDevOmciCC.GetOmciCounters(), nil
3967}
3968
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303969//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003970func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3971 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003972 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003973 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003974 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003975}
3976
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003977func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003978 var pAdapterFsm *cmn.AdapterFsm
3979 //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 +00003980 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003981 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003982 {
mpagenkofbf577d2021-10-12 11:44:33 +00003983 if dh.pOnuOmciDevice != nil {
3984 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3985 } else {
3986 return true //FSM not active - so there is no activity on omci
3987 }
mpagenkof1fc3862021-02-16 10:09:52 +00003988 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003989 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003990 {
mpagenkofbf577d2021-10-12 11:44:33 +00003991 if dh.pOnuOmciDevice != nil {
3992 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3993 } else {
3994 return true //FSM not active - so there is no activity on omci
3995 }
mpagenkof1fc3862021-02-16 10:09:52 +00003996 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003997 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003998 {
mpagenkofbf577d2021-10-12 11:44:33 +00003999 if dh.pLockStateFsm != nil {
4000 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4001 } else {
4002 return true //FSM not active - so there is no activity on omci
4003 }
mpagenkof1fc3862021-02-16 10:09:52 +00004004 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004006 {
mpagenkofbf577d2021-10-12 11:44:33 +00004007 if dh.pUnlockStateFsm != nil {
4008 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4009 } else {
4010 return true //FSM not active - so there is no activity on omci
4011 }
mpagenkof1fc3862021-02-16 10:09:52 +00004012 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004013 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004014 {
mpagenkofbf577d2021-10-12 11:44:33 +00004015 if dh.pOnuMetricsMgr != nil {
4016 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004017 } else {
4018 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004019 }
4020 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004021 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004022 {
4023 dh.lockUpgradeFsm.RLock()
4024 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004025 if dh.pOnuUpradeFsm != nil {
4026 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4027 } else {
4028 return true //FSM not active - so there is no activity on omci
4029 }
mpagenko80622a52021-02-09 16:53:23 +00004030 }
mpagenkof1fc3862021-02-16 10:09:52 +00004031 default:
4032 {
4033 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004034 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004035 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004036 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004037 }
mpagenkofbf577d2021-10-12 11:44:33 +00004038 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4039 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4040 }
4041 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004042}
4043
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004044func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4045 for _, v := range dh.pOnuTP.PAniConfigFsm {
4046 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004047 return false
4048 }
4049 }
4050 return true
4051}
4052
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304053//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004054func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004055 dh.lockVlanConfig.RLock()
4056 defer dh.lockVlanConfig.RUnlock()
4057 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004058 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004059 return false
4060 }
4061 }
4062 return true //FSM not active - so there is no activity on omci
4063}
4064
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304065//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004066func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4067 dh.lockVlanConfig.RLock()
4068 defer dh.lockVlanConfig.RUnlock()
4069 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004070 if v.PAdaptFsm.PFsm != nil {
4071 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004072 return true //there is at least one VLAN FSM with some active configuration
4073 }
4074 }
4075 }
4076 return false //there is no VLAN FSM with some active configuration
4077}
4078
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004080 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4081 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4082 return false
4083 }
4084 }
4085 // a further check is done to identify, if at least some data traffic related configuration exists
4086 // 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])
4087 return dh.checkUserServiceExists(ctx)
4088}
4089
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004090func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304091 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 +00004092 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004093 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004094 // TODO: fatal error reset ONU, delete deviceHandler!
4095 return
4096 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004097 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4098 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004099}
4100
4101func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4102 dh.mutexCollectorFlag.Lock()
4103 dh.collectorIsRunning = flagValue
4104 dh.mutexCollectorFlag.Unlock()
4105}
4106
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004107func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004108 dh.mutexCollectorFlag.RLock()
4109 flagValue := dh.collectorIsRunning
4110 dh.mutexCollectorFlag.RUnlock()
4111 return flagValue
4112}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304113
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304114func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4115 dh.mutextAlarmManagerFlag.Lock()
4116 dh.alarmManagerIsRunning = flagValue
4117 dh.mutextAlarmManagerFlag.Unlock()
4118}
4119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004120func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304121 dh.mutextAlarmManagerFlag.RLock()
4122 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004123 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304124 dh.mutextAlarmManagerFlag.RUnlock()
4125 return flagValue
4126}
4127
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004128func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004129 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304130
4131 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304133 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304134 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304135 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304136 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004137 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4138 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304139 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304140 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004141 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4142 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304143 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304144 }
4145}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004146
Girish Gowdrae95687a2021-09-08 16:30:58 -07004147func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4148 dh.mutexFlowMonitoringRoutineFlag.Lock()
4149 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004150 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004151 dh.isFlowMonitoringRoutineActive[uniID] = flag
4152}
4153
4154func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4155 dh.mutexFlowMonitoringRoutineFlag.RLock()
4156 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4157 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004158 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304159 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4160 return dh.isFlowMonitoringRoutineActive[uniID]
4161 }
4162 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004163}
4164
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004165func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304166 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004167
Maninder7961d722021-06-16 22:10:28 +05304168 connectStatus := voltha.ConnectStatus_UNREACHABLE
4169 operState := voltha.OperStatus_UNKNOWN
4170
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004171 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004172 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004173 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004174 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004175 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004176 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304177 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004178 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4179 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4180 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4181 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4182 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4183 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4184 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4185 // However, a later refactoring of the functionality remains unaffected.
4186 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004187 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004188 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304189 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004190 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304191 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004192 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004193 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304194 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004195 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4196 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304197 operState = voltha.OperStatus_ACTIVE
4198 } else {
4199 operState = voltha.OperStatus_ACTIVATING
4200 }
4201 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004202 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4203 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4204 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304205 operState = voltha.OperStatus_DISCOVERED
4206 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004207 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004208 logger.Debugw(ctx, "Core DeviceStateUpdate",
4209 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304210 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304211 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004212 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004213 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004214 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004215 ConnStatus: connectStatus,
4216 OperStatus: operState,
4217 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304218 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004219 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304220 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004221 } else {
Maninderb5187552021-03-23 22:23:42 +05304222 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004223 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304224
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004225 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304226 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004227 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004228 } else {
4229 onuDevEntry.MutexPersOnuConfig.RLock()
4230 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4231 connectStatus = voltha.ConnectStatus_REACHABLE
4232 }
4233 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304234 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004235 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004236 }
mpagenko101ac942021-11-16 15:01:29 +00004237 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004238 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004239 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004240 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304241
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004242 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304243 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004244 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004245 } else {
4246 onuDevEntry.MutexPersOnuConfig.RLock()
4247 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4248 connectStatus = voltha.ConnectStatus_REACHABLE
4249 }
4250 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304251 }
4252
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004253 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304254
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004255 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004256 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004257 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004258 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004259 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004260
4261 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4262 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4263 } else {
4264 onuDevEntry.MutexReconciledTpInstances.Lock()
4265 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4266 onuDevEntry.MutexReconciledTpInstances.Unlock()
4267 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004268 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004269 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004270 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304271 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004272 dh.reconciling = cSkipOnuConfigReconciling
4273 } else {
4274 dh.reconciling = cOnuConfigReconciling
4275 }
4276 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004277}
4278
mpagenko101ac942021-11-16 15:01:29 +00004279func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304280 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004281 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004282 dh.sendChReconcileFinished(success)
4283 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4284 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4285 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004286 } else {
mpagenko101ac942021-11-16 15:01:29 +00004287 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004288 }
4289}
4290
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004291func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004292 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004293 defer dh.mutexReconcilingFlag.RUnlock()
4294 return dh.reconciling != cNoReconciling
4295}
4296
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004297func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004298 dh.mutexReconcilingFlag.RLock()
4299 defer dh.mutexReconcilingFlag.RUnlock()
4300 return dh.reconciling == cSkipOnuConfigReconciling
4301}
4302
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004303func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4304 dh.mutexReconcilingFirstPassFlag.Lock()
4305 dh.reconcilingFirstPass = value
4306 dh.mutexReconcilingFirstPassFlag.Unlock()
4307}
4308
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004309func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4310 dh.mutexReconcilingReasonUpdate.Lock()
4311 dh.reconcilingReasonUpdate = value
4312 dh.mutexReconcilingReasonUpdate.Unlock()
4313}
4314
4315func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4316 dh.mutexReconcilingReasonUpdate.RLock()
4317 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4318 return dh.reconcilingReasonUpdate
4319}
4320
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004321func (dh *deviceHandler) getDeviceReason() uint8 {
4322 dh.mutexDeviceReason.RLock()
4323 value := dh.deviceReason
4324 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004325 return value
4326}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004327
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004328func (dh *deviceHandler) GetDeviceReasonString() string {
4329 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004330}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004331
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004332func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004333 dh.mutexReadyForOmciConfig.Lock()
4334 dh.readyForOmciConfig = flagValue
4335 dh.mutexReadyForOmciConfig.Unlock()
4336}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004337func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004338 dh.mutexReadyForOmciConfig.RLock()
4339 flagValue := dh.readyForOmciConfig
4340 dh.mutexReadyForOmciConfig.RUnlock()
4341 return flagValue
4342}
Maninder7961d722021-06-16 22:10:28 +05304343
4344func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004345 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304346 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004347 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304348 }
4349
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004350 logger.Debugw(ctx, "Core DeviceStateUpdate",
4351 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004352 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004353 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004354 ConnStatus: connectStatus,
4355 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4356 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304357 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004358 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304359 }
4360}
khenaidoo7d3c5582021-08-11 18:09:44 -04004361
4362/*
4363Helper functions to communicate with Core
4364*/
4365
4366func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4367 cClient, err := dh.coreClient.GetCoreServiceClient()
4368 if err != nil || cClient == nil {
4369 return nil, err
4370 }
4371 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4372 defer cancel()
4373 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4374 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4375}
4376
khenaidoo42dcdfd2021-10-19 17:34:12 -04004377func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004378 cClient, err := dh.coreClient.GetCoreServiceClient()
4379 if err != nil || cClient == nil {
4380 return err
4381 }
4382 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4383 defer cancel()
4384 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004385 logger.Debugw(subCtx, "device-updated-in-core",
4386 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004387 return err
4388}
4389
4390func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4391 cClient, err := dh.coreClient.GetCoreServiceClient()
4392 if err != nil || cClient == nil {
4393 return err
4394 }
4395 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4396 defer cancel()
4397 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004398 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4399 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004400 return err
4401}
4402
4403func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4404 cClient, err := dh.coreClient.GetCoreServiceClient()
4405 if err != nil || cClient == nil {
4406 return err
4407 }
4408 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4409 defer cancel()
4410 _, err = cClient.DeviceUpdate(subCtx, device)
4411 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4412 return err
4413}
4414
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004415func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004416 cClient, err := dh.coreClient.GetCoreServiceClient()
4417 if err != nil || cClient == nil {
4418 return err
4419 }
4420 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4421 defer cancel()
4422 _, err = cClient.PortCreated(subCtx, port)
4423 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4424 return err
4425}
4426
khenaidoo42dcdfd2021-10-19 17:34:12 -04004427func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004428 cClient, err := dh.coreClient.GetCoreServiceClient()
4429 if err != nil || cClient == nil {
4430 return err
4431 }
4432 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4433 defer cancel()
4434 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004435 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 -04004436 return err
4437}
4438
khenaidoo42dcdfd2021-10-19 17:34:12 -04004439func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004440 cClient, err := dh.coreClient.GetCoreServiceClient()
4441 if err != nil || cClient == nil {
4442 return err
4443 }
4444 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4445 defer cancel()
4446 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004447 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 -04004448 return err
4449}
4450
4451/*
4452Helper functions to communicate with parent adapter
4453*/
4454
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004455func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4456 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4457
4458 var request = ia.TechProfileInstanceRequestMessage{
4459 DeviceId: dh.DeviceID,
4460 TpInstancePath: aTpPath,
4461 ParentDeviceId: dh.parentID,
4462 ParentPonPort: dh.device.ParentPortNo,
4463 OnuId: dh.device.ProxyAddress.OnuId,
4464 UniId: uint32(aUniID),
4465 }
4466
4467 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004468 if err != nil || pgClient == nil {
4469 return nil, err
4470 }
4471 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4472 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004473 logger.Debugw(subCtx, "get-tech-profile-instance",
4474 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004475 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004476}
4477
Girish Gowdrae95687a2021-09-08 16:30:58 -07004478// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4479// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4480func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4481 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4482 dh.setFlowMonitoringIsRunning(uniID, true)
4483 for {
4484 select {
4485 // block on the channel to receive an incoming flow
4486 // process the flow completely before proceeding to handle the next flow
4487 case flowCb := <-dh.flowCbChan[uniID]:
4488 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304489 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004490 respChan := make(chan error)
4491 if flowCb.addFlow {
4492 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4493 } else {
4494 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4495 }
4496 // Block on response and tunnel it back to the caller
4497 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304498 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004499 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4500 case <-dh.stopFlowMonitoringRoutine[uniID]:
4501 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4502 dh.setFlowMonitoringIsRunning(uniID, false)
4503 return
4504 }
4505 }
4506}
4507
kesavand011d5162021-11-25 19:21:06 +05304508func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4509 request.ParentDeviceId = dh.GetProxyAddressID()
4510 request.ChildDeviceId = dh.DeviceID
4511 request.ProxyAddress = dh.GetProxyAddress()
4512 request.ConnectStatus = common.ConnectStatus_REACHABLE
4513
4514 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4515 if err != nil || pgClient == nil {
4516 return err
4517 }
4518 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4519 defer cancel()
4520 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4521 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4522 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004523 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4524 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304525 }
4526 return err
4527}
4528
khenaidoo42dcdfd2021-10-19 17:34:12 -04004529func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004530 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4531 if err != nil || pgClient == nil {
4532 return err
4533 }
4534 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4535 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004536 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004537 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004538 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4539 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004540 if status.Code(err) == codes.Unavailable {
4541 dh.setOltAvailable(false)
4542 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004543 logger.Errorw(ctx, "omci-failure",
4544 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004545 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004546 }
4547 return err
4548}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004549
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004550func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4551 // Check if there are additional TCONT instances necessary/available
4552 pDevEntry.MutexPersOnuConfig.Lock()
4553 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4554 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4555 pDevEntry.MutexPersOnuConfig.Unlock()
4556 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4557 logger.Debugw(ctx, "checking available TCONT instances",
4558 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4559 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4560 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4561 log.Fields{"device-id": dh.device.Id})
4562 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304563 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004564 }
4565 } else {
4566 pDevEntry.MutexPersOnuConfig.Unlock()
4567 }
4568 // Check if there are enough PrioQueue instances available
4569 if dh.pOnuTP != nil {
4570 var numberOfUsPrioQueueDbInsts int
4571
4572 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4573 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304574 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004575 numberOfUsPrioQueueDbInsts++
4576 }
4577 }
4578 // Check if there is an upstream PriorityQueue instance available for each Gem port
4579 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4580 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4581 log.Fields{"device-id": dh.DeviceID,
4582 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4583 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4584 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4585
4586 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4587 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4588 log.Fields{"device-id": dh.device.Id})
4589 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304590 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 +00004591 }
4592 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4593 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4594 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4595 } else {
4596 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4597 log.Fields{"device-id": dh.DeviceID})
4598 }
4599 return nil
4600}
4601
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004602// GetDeviceID - TODO: add comment
4603func (dh *deviceHandler) GetDeviceID() string {
4604 return dh.DeviceID
4605}
4606
4607// GetProxyAddressID - TODO: add comment
4608func (dh *deviceHandler) GetProxyAddressID() string {
4609 return dh.device.ProxyAddress.GetDeviceId()
4610}
4611
4612// GetProxyAddressType - TODO: add comment
4613func (dh *deviceHandler) GetProxyAddressType() string {
4614 return dh.device.ProxyAddress.GetDeviceType()
4615}
4616
4617// GetProxyAddress - TODO: add comment
4618func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4619 return dh.device.ProxyAddress
4620}
4621
4622// GetEventProxy - TODO: add comment
4623func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4624 return dh.EventProxy
4625}
4626
4627// GetOmciTimeout - TODO: add comment
4628func (dh *deviceHandler) GetOmciTimeout() int {
4629 return dh.pOpenOnuAc.omciTimeout
4630}
4631
4632// GetAlarmAuditInterval - TODO: add comment
4633func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4634 return dh.pOpenOnuAc.alarmAuditInterval
4635}
4636
4637// GetDlToOnuTimeout4M - TODO: add comment
4638func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4639 return dh.pOpenOnuAc.dlToOnuTimeout4M
4640}
4641
4642// GetUniEntityMap - TODO: add comment
4643func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4644 return &dh.uniEntityMap
4645}
4646
4647// GetPonPortNumber - TODO: add comment
4648func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4649 return &dh.ponPortNumber
4650}
4651
4652// GetUniVlanConfigFsm - TODO: add comment
4653func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004654 dh.lockVlanConfig.RLock()
4655 value := dh.UniVlanConfigFsmMap[uniID]
4656 dh.lockVlanConfig.RUnlock()
4657 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004658}
4659
4660// GetOnuAlarmManager - TODO: add comment
4661func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4662 return dh.pAlarmMgr
4663}
4664
4665// GetOnuMetricsManager - TODO: add comment
4666func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4667 return dh.pOnuMetricsMgr
4668}
4669
4670// GetOnuTP - TODO: add comment
4671func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4672 return dh.pOnuTP
4673}
4674
4675// GetBackendPathPrefix - TODO: add comment
4676func (dh *deviceHandler) GetBackendPathPrefix() string {
4677 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4678}
4679
4680// GetOnuIndication - TODO: add comment
4681func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4682 return dh.pOnuIndication
4683}
4684
4685// RLockMutexDeletionInProgressFlag - TODO: add comment
4686func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4687 dh.mutexDeletionInProgressFlag.RLock()
4688}
4689
4690// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4691func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4692 dh.mutexDeletionInProgressFlag.RUnlock()
4693}
4694
4695// GetDeletionInProgress - TODO: add comment
4696func (dh *deviceHandler) GetDeletionInProgress() bool {
4697 return dh.deletionInProgress
4698}
4699
4700// GetPmConfigs - TODO: add comment
4701func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4702 return dh.pmConfigs
4703}
4704
4705// GetDeviceType - TODO: add comment
4706func (dh *deviceHandler) GetDeviceType() string {
4707 return dh.DeviceType
4708}
4709
4710// GetLogicalDeviceID - TODO: add comment
4711func (dh *deviceHandler) GetLogicalDeviceID() string {
4712 return dh.logicalDeviceID
4713}
4714
4715// GetDevice - TODO: add comment
4716func (dh *deviceHandler) GetDevice() *voltha.Device {
4717 return dh.device
4718}
4719
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004720func (dh *deviceHandler) setOltAvailable(value bool) {
4721 dh.mutexOltAvailable.Lock()
4722 dh.oltAvailable = value
4723 dh.mutexOltAvailable.Unlock()
4724}
4725
4726// IsOltAvailable - TODO: add comment
4727func (dh *deviceHandler) IsOltAvailable() bool {
4728 dh.mutexOltAvailable.RLock()
4729 defer dh.mutexOltAvailable.RUnlock()
4730 return dh.oltAvailable
4731}
4732
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004733// GetMetricsEnabled - TODO: add comment
4734func (dh *deviceHandler) GetMetricsEnabled() bool {
4735 return dh.pOpenOnuAc.MetricsEnabled
4736}
4737
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004738// GetExtendedOmciSupportEnabled - TODO: add comment
4739func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4740 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4741}
4742
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304743// GetExtendedOmciSupportEnabled - TODO: add comment
4744func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
4745 return dh.pOpenOnuAc.skipOnuConfig
4746}
4747
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004748// InitPmConfigs - TODO: add comment
4749func (dh *deviceHandler) InitPmConfigs() {
4750 dh.pmConfigs = &voltha.PmConfigs{}
4751}
4752
4753// GetUniPortMask - TODO: add comment
4754func (dh *deviceHandler) GetUniPortMask() int {
4755 return dh.pOpenOnuAc.config.UniPortMask
4756}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004757
4758func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4759 tpPathFound := false
4760 for _, tpPath := range aTpPathMap {
4761 if tpPath != "" {
4762 tpPathFound = true
4763 }
4764 }
4765 return tpPathFound
4766}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004767
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304768func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4769 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4770 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4771 return resp
4772}
4773
Akash Reddy Kankanalac28f0e22025-06-16 11:00:55 +05304774// getONUGEMStatsInfo - Get the GEM PM history data of the request ONT device
4775func (dh *deviceHandler) getONUGEMStatsInfo(ctx context.Context) *extension.SingleGetValueResponse {
4776 resp := dh.pOnuMetricsMgr.GetONUGEMCounters(ctx)
4777 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4778 return resp
4779}
4780
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05304781func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
4782 return dh.deviceDeleteCommChan
4783}
4784
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004785// PrepareForGarbageCollection - remove references to prepare for garbage collection
4786func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4787 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4788
4789 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4790 // first let the objects rest for some time to give all asynchronously started
4791 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004792 time.Sleep(2 * time.Second)
4793
4794 if dh.pOnuOmciDevice != nil {
4795 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4796 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4797 // reset handling (even in future coding), request monitoring is canceled here one last time to
4798 // be sure that all corresponding go routines are terminated
4799 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4800 }
4801 }
4802 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004803
4804 if dh.pOnuTP != nil {
4805 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4806 }
4807 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004808 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4809 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004810 select {
4811 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4812 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4813 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4814 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004815 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004816 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004817 }
4818 if dh.pAlarmMgr != nil {
4819 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4820 }
4821 if dh.pSelfTestHdlr != nil {
4822 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4823 }
4824 if dh.pLockStateFsm != nil {
4825 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4826 }
4827 if dh.pUnlockStateFsm != nil {
4828 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4829 }
4830 if dh.pOnuUpradeFsm != nil {
4831 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4832 }
4833 if dh.pOnuOmciDevice != nil {
4834 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4835 }
4836 for k, v := range dh.UniVlanConfigFsmMap {
4837 v.PrepareForGarbageCollection(ctx, aDeviceID)
4838 delete(dh.UniVlanConfigFsmMap, k)
4839 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05304840 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004841 dh.pOnuOmciDevice = nil
4842 dh.pOnuTP = nil
4843 dh.pOnuMetricsMgr = nil
4844 dh.pAlarmMgr = nil
4845 dh.pSelfTestHdlr = nil
4846 dh.pLockStateFsm = nil
4847 dh.pUnlockStateFsm = nil
4848 dh.pOnuUpradeFsm = nil
4849}