blob: bab59efab28da2d0d580cdeb8e9a9351158a3bfb [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 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302243 return nil
mpagenko900ee4b2020-10-12 11:56:34 +00002244 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002245 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002246 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002247 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 pDevEntry.MutexOnuImageStatus.RLock()
2249 if pDevEntry.POnuImageStatus != nil {
2250 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002251 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002252 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002253
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002254 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002255 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002256 }
2257 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002259 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002261 }
mpagenko101ac942021-11-16 15:01:29 +00002262 //stop any deviceHandler reconcile processing (if running)
2263 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002264 //port lock/unlock FSM's may be active
2265 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002266 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002267 }
2268 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002270 }
2271 //techProfile related PonAniConfigFsm FSM may be active
2272 if dh.pOnuTP != nil {
2273 // should always be the case here
2274 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 if dh.pOnuTP.PAniConfigFsm != nil {
2276 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2277 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002278 }
mpagenko900ee4b2020-10-12 11:56:34 +00002279 }
2280 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002281 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002282 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002284 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002285 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002286 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002287 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002288 } else {
2289 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002290 }
2291 }
2292 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302293
2294 dh.mutexCollectorFlag.Lock()
2295 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2296 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002297 // Stop collector routine
2298 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302299 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002300 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302301 dh.mutexCollectorFlag.Unlock()
2302
2303 dh.mutextAlarmManagerFlag.Lock()
2304 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2305 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302306 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302307 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302308 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302309 dh.mutextAlarmManagerFlag.Unlock()
2310
2311 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2312 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2313 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302315 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002316 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302317 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302318
Girish Gowdrae95687a2021-09-08 16:30:58 -07002319 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2320
mpagenko80622a52021-02-09 16:53:23 +00002321 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002323 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002324 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002326 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002327 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002328 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2329 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2330 // (even though it may also run into direct cancellation, a bit hard to verify here)
2331 // so don't set 'dh.upgradeCanceled = true' here!
2332 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2333 }
mpagenko38662d02021-08-11 09:45:19 +00002334 }
mpagenko80622a52021-02-09 16:53:23 +00002335
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002336 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002337 return nil
2338}
2339
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302340//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002341func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2342 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 +05302343
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002344 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002346 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002348 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002349 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002351
mpagenkoa40e99a2020-11-17 13:50:39 +00002352 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2353 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2354 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2355 * disable/enable toggling here to allow traffic
2356 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2357 * like the py comment says:
2358 * # start by locking all the unis till mib sync and initial mib is downloaded
2359 * # this way we can capture the port down/up events when we are ready
2360 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302361
mpagenkoa40e99a2020-11-17 13:50:39 +00002362 // Init Uni Ports to Admin locked state
2363 // *** should generate UniLockStateDone event *****
2364 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002366 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002367 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002369 }
2370}
2371
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302372//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002373func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2374 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 /* Mib download procedure -
2376 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2377 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002379 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002380 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002381 return
2382 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302384 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 if pMibDlFsm.Is(mib.DlStDisabled) {
2386 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2387 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 +05302388 // maybe try a FSM reset and then again ... - TODO!!!
2389 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002390 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302391 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002392 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2393 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302394 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002395 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302396 //Begin MIB data download (running autonomously)
2397 }
2398 }
2399 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002400 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002401 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302402 // maybe try a FSM reset and then again ... - TODO!!!
2403 }
2404 /***** Mib download started */
2405 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302407 }
2408}
2409
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302410//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302412 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002413 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2414 if pDevEntry == nil {
2415 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2416 return
2417 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002418 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002419 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002421 // update device info in core
2422 pDevEntry.MutexPersOnuConfig.RLock()
2423 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2424 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2425 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2426 pDevEntry.MutexPersOnuConfig.RUnlock()
2427 dh.logicalDeviceID = dh.DeviceID
2428 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2429 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2430 }
2431 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002432 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2433 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2434 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2435 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002436 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002437 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002438 ConnStatus: voltha.ConnectStatus_REACHABLE,
2439 OperStatus: voltha.OperStatus_ACTIVE,
2440 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302441 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302443 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002444 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302445 }
2446 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302447 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002448 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302449 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002450 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002451
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002453 var waitForOmciProcessor sync.WaitGroup
2454 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002455 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002456 go dh.StartCollector(ctx, &waitForOmciProcessor)
2457 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002458 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 if !dh.GetAlarmManagerIsRunning(ctx) {
2460 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002461 }
2462
Girish Gowdrae95687a2021-09-08 16:30:58 -07002463 // Start flow handler routines per UNI
2464 for _, uniPort := range dh.uniEntityMap {
2465 // only if this port was enabled for use by the operator at startup
2466 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2467 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2468 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2469 }
2470 }
2471 }
2472
Girish Gowdrae0140f02021-02-02 16:55:09 -08002473 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002474 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002475 // There is no way we should be landing here, but if we do then
2476 // there is nothing much we can do about this other than log error
2477 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2478 }
2479
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002480 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002481
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 pDevEntry.MutexPersOnuConfig.RLock()
2483 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2484 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302485 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002487 dh.mutexForDisableDeviceRequested.Lock()
2488 dh.disableDeviceRequested = true
2489 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002490 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002491 // reconcilement will be continued after ani config is done
2492 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002494 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002495 dh.mutexForDisableDeviceRequested.RLock()
2496 if !dh.disableDeviceRequested {
2497 if dh.pUnlockStateFsm == nil {
2498 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2499 } else { //UnlockStateFSM already init
2500 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2501 dh.runUniLockFsm(ctx, false)
2502 }
2503 dh.mutexForDisableDeviceRequested.RUnlock()
2504 } else {
2505 dh.mutexForDisableDeviceRequested.RUnlock()
2506 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002507 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302508 }
2509}
2510
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302511//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2513 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302514
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 if !dh.IsReconciling() {
2516 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002517 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2519 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002520 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002522 return
2523 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 pDevEntry.MutexPersOnuConfig.Lock()
2525 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2526 pDevEntry.MutexPersOnuConfig.Unlock()
2527 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002529 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002530 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302531 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302532 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 +00002533 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002534 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302535
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002536 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302537
Himani Chawla26e555c2020-08-31 12:30:20 +05302538 }
2539}
2540
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302541//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002543 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002544 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002545
mpagenko44bd8362021-11-15 11:40:05 +00002546 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002547 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002549 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002550 OperStatus: voltha.OperStatus_UNKNOWN,
2551 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002552 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002554 }
2555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002557 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002558 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002559
2560 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002562
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002563 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002564 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002566 return
2567 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002568 pDevEntry.MutexPersOnuConfig.Lock()
2569 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2570 pDevEntry.MutexPersOnuConfig.Unlock()
2571 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002572 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002573 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002574 }
mpagenko900ee4b2020-10-12 11:56:34 +00002575}
2576
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302577//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002579 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002581 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002583 ConnStatus: voltha.ConnectStatus_REACHABLE,
2584 OperStatus: voltha.OperStatus_ACTIVE,
2585 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002586 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002587 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002588 }
2589
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002592 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002593 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002594
2595 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002598 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002599 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002600 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002601 return
2602 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 pDevEntry.MutexPersOnuConfig.Lock()
2604 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2605 pDevEntry.MutexPersOnuConfig.Unlock()
2606 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002608 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002609 }
mpagenko900ee4b2020-10-12 11:56:34 +00002610}
2611
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302612//nolint:unparam
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002613func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2614 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2615 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002616 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002617 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002618 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002619 OperStatus: voltha.OperStatus_FAILED,
2620 }); err != nil {
2621 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2622 }
2623}
2624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2626 if devEvent == cmn.OmciAniConfigDone {
2627 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002628 // attention: the device reason update is done based on ONU-UNI-Port related activity
2629 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002631 // 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 +00002632 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002635 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2636 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2637 dh.mutexReconcilingFirstPassFlag.Lock()
2638 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302639 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002640 dh.reconcilingFirstPass = false
2641 go dh.ReconcileDeviceFlowConfig(ctx)
2642 }
2643 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002644 }
2645 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002647 // attention: the device reason update is done based on ONU-UNI-Port related activity
2648 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002650 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2651 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002652 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002653 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302654}
2655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002657 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302659 // attention: the device reason update is done based on ONU-UNI-Port related activity
2660 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302661
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2663 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002664 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002665 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002666 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002667 }
2668 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002670 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002671 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002672 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302673 }
mpagenkof1fc3862021-02-16 10:09:52 +00002674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002676 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002678 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002679 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002680 }
2681 } else {
2682 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002684 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302685}
2686
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302687// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302689 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002691 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002692 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002693 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002695 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002696 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002697 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002699 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002700 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002701 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002703 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002704 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002705 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002706 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002707 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002708 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002709 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002710 case cmn.UniEnableStateFailed:
2711 {
2712 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2713 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002715 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002716 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002717 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002719 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002720 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002721 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002723 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002724 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002725 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002726 default:
2727 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002729 }
2730 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002731}
2732
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002734 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002735 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302736 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002737 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002738 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002739 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302740 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002742 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002743 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 +00002744 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002745 //store UniPort with the System-PortNumber key
2746 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002748 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002749 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002750 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002751 } //error logging already within UniPort method
2752 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302753 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002754 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002755 }
2756 }
2757}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002758
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2760 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002761 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002763 return
2764 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002765 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002767 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2768 for _, mgmtEntityID := range pptpInstKeys {
2769 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002771 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2772 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002773 }
2774 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002776 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002778 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2779 for _, mgmtEntityID := range veipInstKeys {
2780 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002782 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2783 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002784 }
2785 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002787 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002788 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002789 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2790 for _, mgmtEntityID := range potsInstKeys {
2791 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002792 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002793 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2794 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002795 }
2796 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002798 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002799 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002800 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002801 return
2802 }
2803
mpagenko2c3f6c52021-11-23 11:22:10 +00002804 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2805 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2806 // 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 -07002807 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2808 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2809 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002810 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2811 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002812 for i := 0; i < int(uniCnt); i++ {
2813 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002814 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002815 }
2816}
2817
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002818// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2819func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002820 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302821 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002822 // with following remark:
2823 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2824 // # load on the core
2825
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002826 // 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 +00002827
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002828 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002829 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002830 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2831 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2832 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2833 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002834 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002835 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002836 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002837 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002838 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 PortNo: port.PortNo,
2840 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002841 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002842 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 -04002843 }
2844 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002845 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302846 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002847 }
mpagenko3af1f032020-06-10 08:53:41 +00002848 }
2849 }
2850}
2851
2852// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2854 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002855 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2856 for uniNo, uniPort := range dh.uniEntityMap {
2857 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002858
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2860 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2861 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2862 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002863 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002864 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002865 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002867 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 PortNo: port.PortNo,
2869 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002870 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 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 -04002872 }
2873 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002874 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302875 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002876 }
2877
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002878 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002879 }
2880}
2881
2882// ONU_Active/Inactive announcement on system KAFKA bus
2883// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002885 var de voltha.DeviceEvent
2886 eventContext := make(map[string]string)
2887 //Populating event context
2888 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002889 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002890 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002892 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002893 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 +00002894 }
2895 oltSerialNumber := parentDevice.SerialNumber
2896
2897 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2898 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2899 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302900 eventContext["olt-serial-number"] = oltSerialNumber
2901 eventContext["device-id"] = aDeviceID
2902 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002903 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2905 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002906 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2907 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2909 deviceEntry.MutexPersOnuConfig.RUnlock()
2910 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002911 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002912 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2913 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2914 } else {
2915 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2916 log.Fields{"device-id": aDeviceID})
2917 return
2918 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002919
2920 /* Populating device event body */
2921 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302922 de.ResourceId = aDeviceID
2923 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002924 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2925 de.Description = fmt.Sprintf("%s Event - %s - %s",
2926 cEventObjectType, cOnuActivatedEvent, "Raised")
2927 } else {
2928 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2929 de.Description = fmt.Sprintf("%s Event - %s - %s",
2930 cEventObjectType, cOnuActivatedEvent, "Cleared")
2931 }
2932 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302933 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302935 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002936 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302937 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302938 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002939}
2940
Himani Chawla4d908332020-08-31 12:30:20 +05302941// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05302943 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002944 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302945 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002947 sFsmName = "LockStateFSM"
2948 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002950 sFsmName = "UnLockStateFSM"
2951 }
mpagenko3af1f032020-06-10 08:53:41 +00002952
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002954 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002956 return
2957 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002959 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302960 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002961 dh.pLockStateFsm = pLSFsm
2962 } else {
2963 dh.pUnlockStateFsm = pLSFsm
2964 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002965 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002966 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002967 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002968 }
2969}
2970
2971// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002972func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002973 /* Uni Port lock/unlock procedure -
2974 ***** should run via 'adminDone' state and generate the argument requested event *****
2975 */
2976 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302977 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002979 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2980 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2982 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002983 }
2984 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002986 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2987 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2989 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002990 }
2991 }
2992 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002993 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2994 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002995 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002996 // maybe try a FSM reset and then again ... - TODO!!!
2997 } else {
2998 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002999 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003000 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003001 }
3002 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003003 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003005 // maybe try a FSM reset and then again ... - TODO!!!
3006 }
3007 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003009 // maybe try a FSM reset and then again ... - TODO!!!
3010 }
3011}
3012
mpagenko80622a52021-02-09 16:53:23 +00003013// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003014// precondition: lockUpgradeFsm is already locked from caller of this function
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303015//
3016//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303018 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003019 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003020 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003021 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303023 return fmt.Errorf("no valid omciCC - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003024 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003026 sFsmName, chUpgradeFsm)
3027 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003029 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3031 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003032 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003033 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303034 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003035 }
mpagenko59862f02021-10-11 08:53:18 +00003036 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003037 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3038 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003039 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3040 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003041 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003043 } else {
3044 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003045 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003046 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303047 return fmt.Errorf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003048 }
3049 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003051 // maybe try a FSM reset and then again ... - TODO!!!
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303052 return fmt.Errorf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003053 }
3054 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003055 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303056 return fmt.Errorf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id)
mpagenko80622a52021-02-09 16:53:23 +00003057 }
3058 return nil
3059}
3060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3062func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003063 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003064 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003065 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003066 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3067 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003068 dh.pLastUpgradeImageState = apImageState
3069 dh.lockUpgradeFsm.Unlock()
3070 //signal upgradeFsm removed using non-blocking channel send
3071 select {
3072 case dh.upgradeFsmChan <- struct{}{}:
3073 default:
3074 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003076 }
mpagenko80622a52021-02-09 16:53:23 +00003077}
3078
mpagenko15ff4a52021-03-02 10:09:20 +00003079// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3080func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003082 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003084 return
3085 }
3086
3087 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003088 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003089 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003090 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3091 dh.lockUpgradeFsm.RUnlock()
3092 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3093 return
3094 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003095 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003096 if pUpgradeStatemachine != nil {
3097 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3098 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099 UpgradeState := pUpgradeStatemachine.Current()
3100 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3101 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3102 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003103 // 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 +00003104 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003105 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3106 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003107 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003108 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003109 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003110 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3111 dh.upgradeCanceled = true
3112 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3113 }
mpagenko15ff4a52021-03-02 10:09:20 +00003114 return
3115 }
mpagenko59862f02021-10-11 08:53:18 +00003116 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003117 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3118 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003119 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003121 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3122 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003123 return
3124 }
3125 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003126 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003127 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3129 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003130 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3131 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003132 return
3133 }
3134 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003135 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003136 }
3137 } else {
3138 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 +00003139 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003140 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3141 dh.upgradeCanceled = true
3142 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3143 }
mpagenko1f8e8822021-06-25 14:10:21 +00003144 }
mpagenko15ff4a52021-03-02 10:09:20 +00003145 return
3146 }
mpagenko59862f02021-10-11 08:53:18 +00003147 dh.lockUpgradeFsm.RUnlock()
3148 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3149 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003150 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3151 dh.upgradeCanceled = true
3152 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3153 }
mpagenko59862f02021-10-11 08:53:18 +00003154 return
3155 }
3156 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3157 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3158 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3159 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3160 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3161 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3162 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003163 }
mpagenko15ff4a52021-03-02 10:09:20 +00003164 }
3165 }
3166 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003168 }
mpagenko59862f02021-10-11 08:53:18 +00003169 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003170}
3171
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303172// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003174
3175 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003176 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003177 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003178 kvbackend := &db.Backend{
3179 Client: dh.pOpenOnuAc.kvClient,
3180 StoreType: dh.pOpenOnuAc.KVStoreType,
3181 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003182 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003183 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3184 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003185
mpagenkoaf801632020-07-03 10:00:42 +00003186 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003187}
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303188
3189//nolint:unparam
khenaidoo7d3c5582021-08-11 18:09:44 -04003190func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303191 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003192
mpagenkodff5dda2020-08-28 11:52:01 +00003193 for _, field := range flow.GetOfbFields(apFlowItem) {
3194 switch field.Type {
3195 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3196 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003198 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3199 }
mpagenko01e726e2020-10-23 09:45:29 +00003200 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003201 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3202 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303203 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003204 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303205 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3206 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003207 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3208 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003209 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003210 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303211 return
mpagenkodff5dda2020-08-28 11:52:01 +00003212 }
3213 }
mpagenko01e726e2020-10-23 09:45:29 +00003214 */
mpagenkodff5dda2020-08-28 11:52:01 +00003215 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3216 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303217 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003218 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303219 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003220 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303221 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003222 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303224 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003225 }
3226 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3227 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303228 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003229 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303230 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003231 }
3232 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3233 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003234 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003235 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3236 }
3237 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3238 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003239 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003240 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3241 }
3242 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3243 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003245 "IPv4-DST": field.GetIpv4Dst()})
3246 }
3247 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3248 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003249 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003250 "IPv4-SRC": field.GetIpv4Src()})
3251 }
3252 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3253 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003254 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003255 "Metadata": field.GetTableMetadata()})
3256 }
3257 /*
3258 default:
3259 {
3260 //all other entires ignored
3261 }
3262 */
3263 }
3264 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303265}
mpagenkodff5dda2020-08-28 11:52:01 +00003266
khenaidoo7d3c5582021-08-11 18:09:44 -04003267func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003268 for _, action := range flow.GetActions(apFlowItem) {
3269 switch action.Type {
3270 /* not used:
3271 case of.OfpActionType_OFPAT_OUTPUT:
3272 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003274 "Output": action.GetOutput()})
3275 }
3276 */
3277 case of.OfpActionType_OFPAT_PUSH_VLAN:
3278 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003280 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3281 }
3282 case of.OfpActionType_OFPAT_SET_FIELD:
3283 {
3284 pActionSetField := action.GetSetField()
3285 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003287 "OxcmClass": pActionSetField.Field.OxmClass})
3288 }
3289 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303290 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003291 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303292 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003293 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303294 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003295 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303296 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003297 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003298 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003299 "Type": pActionSetField.Field.GetOfbField().Type})
3300 }
3301 }
3302 /*
3303 default:
3304 {
3305 //all other entires ignored
3306 }
3307 */
3308 }
3309 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303310}
3311
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303312// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003313func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003314 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303315 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3316 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303317 var loSetPcp uint8
3318 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303319 var loIPProto uint32
3320 /* the TechProfileId is part of the flow Metadata - compare also comment within
3321 * OLT-Adapter:openolt_flowmgr.go
3322 * Metadata 8 bytes:
3323 * Most Significant 2 Bytes = Inner VLAN
3324 * Next 2 Bytes = Tech Profile ID(TPID)
3325 * Least Significant 4 Bytes = Port ID
3326 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3327 * subscriber related flows.
3328 */
3329
dbainbri4d3a0dc2020-12-02 00:33:42 +00003330 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303331 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003332 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003334 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303335 }
mpagenko551a4d42020-12-08 18:09:20 +00003336 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003337 loCookie := apFlowItem.GetCookie()
3338 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303339 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003340 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303341 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303342
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303343 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003344 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303345 if loIPProto == 2 {
3346 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3347 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003348 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303350 return nil
3351 }
mpagenko01e726e2020-10-23 09:45:29 +00003352 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003353 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003354
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303355 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3356 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003357 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003359 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3360 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3361 //TODO!!: Use DeviceId within the error response to rwCore
3362 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003363 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003364 }
3365 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003367 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303368 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3369 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3370 loSetVlan = loMatchVlan
3371 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 +00003372 } else {
3373 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3374 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3375 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303376 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003377 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003378 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003379 }
mpagenko9a304ea2020-12-16 15:54:01 +00003380
khenaidoo42dcdfd2021-10-19 17:34:12 -04003381 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003382 if apFlowMetaData != nil {
3383 meter = apFlowMetaData.Meters[0]
3384 }
mpagenkobc4170a2021-08-17 16:42:10 +00003385 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3386 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3387 // when different rules are requested concurrently for the same uni
3388 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3389 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3390 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3392 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003393 //SetUniFlowParams() may block on some rule that is suspended-to-add
3394 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003395 // Also the error is returned to caller via response channel
3396 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303397 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003398 dh.lockVlanConfig.RUnlock()
3399 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003400 return
mpagenkodff5dda2020-08-28 11:52:01 +00003401 }
mpagenkobc4170a2021-08-17 16:42:10 +00003402 dh.lockVlanConfig.RUnlock()
3403 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003404 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303405 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003406 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003407 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003408 if err != nil {
3409 *respChan <- err
3410 }
mpagenko01e726e2020-10-23 09:45:29 +00003411}
3412
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303413// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003414func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003415 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3416 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3417 //no extra check is done on the rule parameters
3418 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3419 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3420 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3421 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003422 // - 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 +00003423 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003425
3426 /* TT related temporary workaround - should not be needed anymore
3427 for _, field := range flow.GetOfbFields(apFlowItem) {
3428 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3429 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003430 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003431 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3432 if loIPProto == 2 {
3433 // 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 +00003434 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003436 return nil
3437 }
3438 }
3439 } //for all OfbFields
3440 */
3441
mpagenko9a304ea2020-12-16 15:54:01 +00003442 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003443 dh.lockVlanConfig.RLock()
3444 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3446 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003447 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3448 return
mpagenko01e726e2020-10-23 09:45:29 +00003449 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003450 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003451 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003452 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003453 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003454 // Push response on the response channel
3455 if respChan != nil {
3456 // 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
3457 select {
3458 case *respChan <- nil:
3459 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3460 default:
3461 }
3462 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003464}
3465
Himani Chawla26e555c2020-08-31 12:30:20 +05303466// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003467// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003468// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303470 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 +05303471 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003472
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003474 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003475 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3476 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003477 }
3478
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303479 if dh.pDeviceStateFsm.Current() == devStDown {
3480 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3481 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3482 }
3483
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3485 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303486 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003487 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003488 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3489 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003490 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3491 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003492 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3494 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003495 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3496 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003497 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003498 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303499 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003500 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3502 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003503 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003504 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003505 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3506 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003507 }
3508 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003509 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 "device-id": dh.DeviceID})
3511 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003512 }
3513 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003514 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3516 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003517 }
3518 return nil
3519}
3520
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303521// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003522// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003523func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003524 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003525 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003526 for _, uniPort := range dh.uniEntityMap {
3527 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003528 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003529 pCurrentUniPort = uniPort
3530 break //found - end search loop
3531 }
3532 }
3533 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003534 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003536 return
3537 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003539}
3540
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303541// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003542func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003543 //TODO!! verify and start pending flow configuration
3544 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3545 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303546 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003547 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003549 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003550 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003552 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003553 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003554 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3556 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003557 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003558 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003559 } else {
3560 /***** UniVlanConfigFsm continued */
3561 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003562 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3563 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003564 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3566 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003567 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003568 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003569 } else {
3570 /***** UniVlanConfigFsm continued */
3571 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003572 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3573 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003574 }
mpagenkodff5dda2020-08-28 11:52:01 +00003575 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003576 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3578 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003579 }
3580 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003581 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 +00003582 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3583 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003584 }
3585 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003586 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003587 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003588 }
mpagenkof1fc3862021-02-16 10:09:52 +00003589 } else {
3590 dh.lockVlanConfig.RUnlock()
3591 }
mpagenkodff5dda2020-08-28 11:52:01 +00003592}
3593
Akash Soni3de0e062024-12-11 16:37:26 +05303594// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3595func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3596 dh.lockVlanConfig.Lock()
3597 defer dh.lockVlanConfig.Unlock()
3598
3599 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3600 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3601 if pVlanFilterStatemachine != nil {
3602 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3603 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3604 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3605 })
3606 } else {
3607 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3608 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3609 })
3610 }
3611 } else {
3612 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3613 "device-id": dh.DeviceID, "UniPort": uniID,
3614 })
3615 }
3616 } else {
3617 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3618 "device-id": dh.DeviceID, "UniPort": uniID,
3619 })
3620 }
3621}
3622
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303623// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003624// 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 +00003625func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003626 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003627 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003628 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003629 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003631 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003632}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003633
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303634// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003636 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3637 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3638 // obviously then parallel processing on the cancel must be avoided
3639 // deadline context to ensure completion of background routines waited for
3640 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3641 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3642 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303643 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003644
Akash Soni840f8d62024-12-11 19:37:06 +05303645 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3646 if err != nil {
3647 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3648 return err
3649 }
3650 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003651}
3652
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303653// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3654// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3656 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003657
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303659 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003660 return nil
3661 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003663
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003664 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003665 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003666 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3667 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003668 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003669 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003670
mpagenkof1fc3862021-02-16 10:09:52 +00003671 if aWriteToKvStore {
3672 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3673 }
3674 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003675}
3676
dbainbri4d3a0dc2020-12-02 00:33:42 +00003677func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003678 defer cancel() //ensure termination of context (may be pro forma)
3679 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003680 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003682}
3683
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303684// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3685//
3686// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003687func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3688 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3689 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3690 dh.mutexDeviceReason.Lock()
3691 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003692 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003693 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003694 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003695 DeviceId: dh.DeviceID,
3696 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003697 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003698 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003700 return err
3701 }
mpagenkoe4782082021-11-25 12:04:26 +00003702 } else {
3703 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 +00003704 }
mpagenkoe4782082021-11-25 12:04:26 +00003705 dh.deviceReason = deviceReason
3706 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3707 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003708 return nil
3709}
3710
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003711func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3712 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003713 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003714 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3715 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003716 }
mpagenkof1fc3862021-02-16 10:09:52 +00003717 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003718}
3719
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003720// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003721// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003722func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3723 dh.lockDevice.RLock()
3724 defer dh.lockDevice.RUnlock()
3725 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003726 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003727 }
3728 return 0, errors.New("error-fetching-uni-port")
3729}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003730
3731// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003732func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3733 var errorsList []error
3734 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 -08003735
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003736 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3737 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3738 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3739
3740 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3741 // successfully.
3742 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3743 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3744 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003745 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 -08003746 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003747 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003748 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003749 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003750}
3751
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003752func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3753 var err error
3754 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003755 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003756
3757 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003759 errorsList = append(errorsList, err)
3760 }
3761 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003762 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003763
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003764 return errorsList
3765}
3766
3767func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3768 var err error
3769 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003770 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003771 // Check if group metric related config is updated
3772 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003773 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3774 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3775 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003776
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003777 if ok && m.Frequency != v.GroupFreq {
3778 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003779 errorsList = append(errorsList, err)
3780 }
3781 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 if ok && m.Enabled != v.Enabled {
3783 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003784 errorsList = append(errorsList, err)
3785 }
3786 }
3787 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003788 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003789 return errorsList
3790}
3791
3792func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3793 var err error
3794 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003795 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003796 // Check if standalone metric related config is updated
3797 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3799 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3800 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802 if ok && m.Frequency != v.SampleFreq {
3803 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003804 errorsList = append(errorsList, err)
3805 }
3806 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003807 if ok && m.Enabled != v.Enabled {
3808 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003809 errorsList = append(errorsList, err)
3810 }
3811 }
3812 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003813 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003814 return errorsList
3815}
3816
3817// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003818func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003819 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003820
3821 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003822 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303823 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003824 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003825 // Initialize the next metric collection time.
3826 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3827 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003828 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003829 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303830 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3831 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003832 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303833
Girish Gowdrae09a6202021-01-12 18:10:59 -08003834 select {
3835 case <-dh.stopCollector:
3836 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003837 // Stop the L2 PM FSM
3838 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3840 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3841 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003842 }
3843 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003844 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003845 }
3846 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003847 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3848 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003849 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3851 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003852 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003853
Girish Gowdrae09a6202021-01-12 18:10:59 -08003854 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303855 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003856 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3857 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3858 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3859 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003860 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003861 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
3862 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003863 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003864 } else {
3865 if dh.pmConfigs.Grouped { // metrics are managed as a group
3866 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003867 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003868
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003869 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3870 // 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 -08003871 // 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 +00003872 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3873 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003874 }
3875 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003876 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3877 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3878 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3879 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003880 }
3881 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003882 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003883
3884 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3886 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3887 // 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 -08003888 // 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 +00003889 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003890 prevInternal := g.NextCollectionInterval
3891 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003892 }
3893 }
3894 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3896 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3897 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003898 prevInternal := m.NextCollectionInterval
3899 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003900 }
3901 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003902 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003903 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003904 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003905 } */
3906 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003907 }
3908 }
3909}
kesavandfdf77632021-01-26 23:40:33 -05003910
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303911//nolint:unparam
Akash Soni3c176c62024-12-04 13:30:43 +05303912func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
3913
3914 singleValResp := extension.SingleSetValueResponse{
3915 Response: &extension.SetValueResponse{
3916 Status: extension.SetValueResponse_OK,
3917 },
3918 }
3919
3920 return &singleValResp
3921}
3922
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003923func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003924
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3926 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003927}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003928
Himani Chawla43f95ff2021-06-03 00:24:12 +05303929func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3930 if dh.pOnuMetricsMgr == nil {
3931 return &extension.SingleGetValueResponse{
3932 Response: &extension.GetValueResponse{
3933 Status: extension.GetValueResponse_ERROR,
3934 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3935 },
3936 }
3937 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303938 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303939 return resp
3940}
3941
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003942func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3943
3944 var err error
3945 var pDevOmciCC *cmn.OmciCC
3946 if dh.pOnuOmciDevice == nil {
3947 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3948 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3949 } else {
3950 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3951 if pDevOmciCC == nil {
3952 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3953 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3954 }
3955 }
3956 if err != nil {
3957 return &extension.SingleGetValueResponse{
3958 Response: &extension.GetValueResponse{
3959 Status: extension.GetValueResponse_ERROR,
3960 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3961 },
3962 },
3963 err
3964 }
3965 return pDevOmciCC.GetOmciCounters(), nil
3966}
3967
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05303968//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003969func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3970 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003971 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003972 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003973 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003974}
3975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003976func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003977 var pAdapterFsm *cmn.AdapterFsm
3978 //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 +00003979 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003981 {
mpagenkofbf577d2021-10-12 11:44:33 +00003982 if dh.pOnuOmciDevice != nil {
3983 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3984 } else {
3985 return true //FSM not active - so there is no activity on omci
3986 }
mpagenkof1fc3862021-02-16 10:09:52 +00003987 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003988 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003989 {
mpagenkofbf577d2021-10-12 11:44:33 +00003990 if dh.pOnuOmciDevice != nil {
3991 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3992 } else {
3993 return true //FSM not active - so there is no activity on omci
3994 }
mpagenkof1fc3862021-02-16 10:09:52 +00003995 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003996 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003997 {
mpagenkofbf577d2021-10-12 11:44:33 +00003998 if dh.pLockStateFsm != nil {
3999 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
4000 } else {
4001 return true //FSM not active - so there is no activity on omci
4002 }
mpagenkof1fc3862021-02-16 10:09:52 +00004003 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004004 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004005 {
mpagenkofbf577d2021-10-12 11:44:33 +00004006 if dh.pUnlockStateFsm != nil {
4007 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
4008 } else {
4009 return true //FSM not active - so there is no activity on omci
4010 }
mpagenkof1fc3862021-02-16 10:09:52 +00004011 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004012 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00004013 {
mpagenkofbf577d2021-10-12 11:44:33 +00004014 if dh.pOnuMetricsMgr != nil {
4015 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00004016 } else {
4017 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004018 }
4019 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004020 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004021 {
4022 dh.lockUpgradeFsm.RLock()
4023 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004024 if dh.pOnuUpradeFsm != nil {
4025 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4026 } else {
4027 return true //FSM not active - so there is no activity on omci
4028 }
mpagenko80622a52021-02-09 16:53:23 +00004029 }
mpagenkof1fc3862021-02-16 10:09:52 +00004030 default:
4031 {
4032 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004033 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004034 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004035 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004036 }
mpagenkofbf577d2021-10-12 11:44:33 +00004037 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4038 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4039 }
4040 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004041}
4042
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4044 for _, v := range dh.pOnuTP.PAniConfigFsm {
4045 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004046 return false
4047 }
4048 }
4049 return true
4050}
4051
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304052//nolint:unparam
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004053func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004054 dh.lockVlanConfig.RLock()
4055 defer dh.lockVlanConfig.RUnlock()
4056 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004057 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004058 return false
4059 }
4060 }
4061 return true //FSM not active - so there is no activity on omci
4062}
4063
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304064//nolint:unparam
mpagenkof1fc3862021-02-16 10:09:52 +00004065func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4066 dh.lockVlanConfig.RLock()
4067 defer dh.lockVlanConfig.RUnlock()
4068 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004069 if v.PAdaptFsm.PFsm != nil {
4070 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004071 return true //there is at least one VLAN FSM with some active configuration
4072 }
4073 }
4074 }
4075 return false //there is no VLAN FSM with some active configuration
4076}
4077
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004078func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004079 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4080 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4081 return false
4082 }
4083 }
4084 // a further check is done to identify, if at least some data traffic related configuration exists
4085 // 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])
4086 return dh.checkUserServiceExists(ctx)
4087}
4088
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004089func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304090 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 +00004091 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004092 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004093 // TODO: fatal error reset ONU, delete deviceHandler!
4094 return
4095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004096 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4097 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004098}
4099
4100func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4101 dh.mutexCollectorFlag.Lock()
4102 dh.collectorIsRunning = flagValue
4103 dh.mutexCollectorFlag.Unlock()
4104}
4105
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004106func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004107 dh.mutexCollectorFlag.RLock()
4108 flagValue := dh.collectorIsRunning
4109 dh.mutexCollectorFlag.RUnlock()
4110 return flagValue
4111}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304112
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304113func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4114 dh.mutextAlarmManagerFlag.Lock()
4115 dh.alarmManagerIsRunning = flagValue
4116 dh.mutextAlarmManagerFlag.Unlock()
4117}
4118
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004119func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304120 dh.mutextAlarmManagerFlag.RLock()
4121 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004122 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304123 dh.mutextAlarmManagerFlag.RUnlock()
4124 return flagValue
4125}
4126
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004127func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004128 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304129
4130 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004131 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304132 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304133 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304134 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304135 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004136 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4137 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304138 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304139 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004140 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4141 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304142 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304143 }
4144}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004145
Girish Gowdrae95687a2021-09-08 16:30:58 -07004146func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4147 dh.mutexFlowMonitoringRoutineFlag.Lock()
4148 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004149 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004150 dh.isFlowMonitoringRoutineActive[uniID] = flag
4151}
4152
4153func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4154 dh.mutexFlowMonitoringRoutineFlag.RLock()
4155 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4156 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004157 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304158 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4159 return dh.isFlowMonitoringRoutineActive[uniID]
4160 }
4161 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004162}
4163
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004164func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304165 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004166
Maninder7961d722021-06-16 22:10:28 +05304167 connectStatus := voltha.ConnectStatus_UNREACHABLE
4168 operState := voltha.OperStatus_UNKNOWN
4169
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004170 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004171 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004172 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004173 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004174 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004175 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304176 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004177 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4178 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4179 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4180 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4181 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4182 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4183 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4184 // However, a later refactoring of the functionality remains unaffected.
4185 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004186 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004187 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304188 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004189 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304190 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004191 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304193 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004194 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4195 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304196 operState = voltha.OperStatus_ACTIVE
4197 } else {
4198 operState = voltha.OperStatus_ACTIVATING
4199 }
4200 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004201 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4202 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4203 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304204 operState = voltha.OperStatus_DISCOVERED
4205 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004206 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004207 logger.Debugw(ctx, "Core DeviceStateUpdate",
4208 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304209 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304210 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004211 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004212 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004213 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004214 ConnStatus: connectStatus,
4215 OperStatus: operState,
4216 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304217 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004218 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304219 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004220 } else {
Maninderb5187552021-03-23 22:23:42 +05304221 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004222 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304223
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004224 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304225 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004226 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004227 } else {
4228 onuDevEntry.MutexPersOnuConfig.RLock()
4229 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4230 connectStatus = voltha.ConnectStatus_REACHABLE
4231 }
4232 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304233 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004234 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004235 }
mpagenko101ac942021-11-16 15:01:29 +00004236 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004237 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004238 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004239 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004241 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304242 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004243 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004244 } else {
4245 onuDevEntry.MutexPersOnuConfig.RLock()
4246 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4247 connectStatus = voltha.ConnectStatus_REACHABLE
4248 }
4249 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304250 }
4251
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004252 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304253
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004254 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004255 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004256 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004257 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004258 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004259
4260 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4261 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4262 } else {
4263 onuDevEntry.MutexReconciledTpInstances.Lock()
4264 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4265 onuDevEntry.MutexReconciledTpInstances.Unlock()
4266 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004267 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004268 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004269 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304270 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004271 dh.reconciling = cSkipOnuConfigReconciling
4272 } else {
4273 dh.reconciling = cOnuConfigReconciling
4274 }
4275 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004276}
4277
mpagenko101ac942021-11-16 15:01:29 +00004278func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304279 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004280 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004281 dh.sendChReconcileFinished(success)
4282 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4283 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4284 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004285 } else {
mpagenko101ac942021-11-16 15:01:29 +00004286 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004287 }
4288}
4289
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004290func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004291 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004292 defer dh.mutexReconcilingFlag.RUnlock()
4293 return dh.reconciling != cNoReconciling
4294}
4295
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004296func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004297 dh.mutexReconcilingFlag.RLock()
4298 defer dh.mutexReconcilingFlag.RUnlock()
4299 return dh.reconciling == cSkipOnuConfigReconciling
4300}
4301
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004302func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4303 dh.mutexReconcilingFirstPassFlag.Lock()
4304 dh.reconcilingFirstPass = value
4305 dh.mutexReconcilingFirstPassFlag.Unlock()
4306}
4307
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004308func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4309 dh.mutexReconcilingReasonUpdate.Lock()
4310 dh.reconcilingReasonUpdate = value
4311 dh.mutexReconcilingReasonUpdate.Unlock()
4312}
4313
4314func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4315 dh.mutexReconcilingReasonUpdate.RLock()
4316 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4317 return dh.reconcilingReasonUpdate
4318}
4319
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004320func (dh *deviceHandler) getDeviceReason() uint8 {
4321 dh.mutexDeviceReason.RLock()
4322 value := dh.deviceReason
4323 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004324 return value
4325}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004326
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004327func (dh *deviceHandler) GetDeviceReasonString() string {
4328 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004329}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004330
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004331func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004332 dh.mutexReadyForOmciConfig.Lock()
4333 dh.readyForOmciConfig = flagValue
4334 dh.mutexReadyForOmciConfig.Unlock()
4335}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004336func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004337 dh.mutexReadyForOmciConfig.RLock()
4338 flagValue := dh.readyForOmciConfig
4339 dh.mutexReadyForOmciConfig.RUnlock()
4340 return flagValue
4341}
Maninder7961d722021-06-16 22:10:28 +05304342
4343func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004344 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304345 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004346 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304347 }
4348
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004349 logger.Debugw(ctx, "Core DeviceStateUpdate",
4350 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004351 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004352 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004353 ConnStatus: connectStatus,
4354 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4355 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304356 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004357 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304358 }
4359}
khenaidoo7d3c5582021-08-11 18:09:44 -04004360
4361/*
4362Helper functions to communicate with Core
4363*/
4364
4365func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4366 cClient, err := dh.coreClient.GetCoreServiceClient()
4367 if err != nil || cClient == nil {
4368 return nil, err
4369 }
4370 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4371 defer cancel()
4372 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4373 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4374}
4375
khenaidoo42dcdfd2021-10-19 17:34:12 -04004376func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004377 cClient, err := dh.coreClient.GetCoreServiceClient()
4378 if err != nil || cClient == nil {
4379 return err
4380 }
4381 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4382 defer cancel()
4383 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004384 logger.Debugw(subCtx, "device-updated-in-core",
4385 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004386 return err
4387}
4388
4389func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4390 cClient, err := dh.coreClient.GetCoreServiceClient()
4391 if err != nil || cClient == nil {
4392 return err
4393 }
4394 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4395 defer cancel()
4396 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004397 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4398 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004399 return err
4400}
4401
4402func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4403 cClient, err := dh.coreClient.GetCoreServiceClient()
4404 if err != nil || cClient == nil {
4405 return err
4406 }
4407 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4408 defer cancel()
4409 _, err = cClient.DeviceUpdate(subCtx, device)
4410 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4411 return err
4412}
4413
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004414func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004415 cClient, err := dh.coreClient.GetCoreServiceClient()
4416 if err != nil || cClient == nil {
4417 return err
4418 }
4419 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4420 defer cancel()
4421 _, err = cClient.PortCreated(subCtx, port)
4422 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4423 return err
4424}
4425
khenaidoo42dcdfd2021-10-19 17:34:12 -04004426func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004427 cClient, err := dh.coreClient.GetCoreServiceClient()
4428 if err != nil || cClient == nil {
4429 return err
4430 }
4431 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4432 defer cancel()
4433 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004434 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 -04004435 return err
4436}
4437
khenaidoo42dcdfd2021-10-19 17:34:12 -04004438func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004439 cClient, err := dh.coreClient.GetCoreServiceClient()
4440 if err != nil || cClient == nil {
4441 return err
4442 }
4443 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4444 defer cancel()
4445 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004446 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 -04004447 return err
4448}
4449
4450/*
4451Helper functions to communicate with parent adapter
4452*/
4453
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004454func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4455 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4456
4457 var request = ia.TechProfileInstanceRequestMessage{
4458 DeviceId: dh.DeviceID,
4459 TpInstancePath: aTpPath,
4460 ParentDeviceId: dh.parentID,
4461 ParentPonPort: dh.device.ParentPortNo,
4462 OnuId: dh.device.ProxyAddress.OnuId,
4463 UniId: uint32(aUniID),
4464 }
4465
4466 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004467 if err != nil || pgClient == nil {
4468 return nil, err
4469 }
4470 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4471 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004472 logger.Debugw(subCtx, "get-tech-profile-instance",
4473 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004474 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004475}
4476
Girish Gowdrae95687a2021-09-08 16:30:58 -07004477// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4478// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4479func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4480 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4481 dh.setFlowMonitoringIsRunning(uniID, true)
4482 for {
4483 select {
4484 // block on the channel to receive an incoming flow
4485 // process the flow completely before proceeding to handle the next flow
4486 case flowCb := <-dh.flowCbChan[uniID]:
4487 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304488 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004489 respChan := make(chan error)
4490 if flowCb.addFlow {
4491 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4492 } else {
4493 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4494 }
4495 // Block on response and tunnel it back to the caller
4496 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304497 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004498 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4499 case <-dh.stopFlowMonitoringRoutine[uniID]:
4500 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4501 dh.setFlowMonitoringIsRunning(uniID, false)
4502 return
4503 }
4504 }
4505}
4506
kesavand011d5162021-11-25 19:21:06 +05304507func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4508 request.ParentDeviceId = dh.GetProxyAddressID()
4509 request.ChildDeviceId = dh.DeviceID
4510 request.ProxyAddress = dh.GetProxyAddress()
4511 request.ConnectStatus = common.ConnectStatus_REACHABLE
4512
4513 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4514 if err != nil || pgClient == nil {
4515 return err
4516 }
4517 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4518 defer cancel()
4519 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4520 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4521 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004522 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4523 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304524 }
4525 return err
4526}
4527
khenaidoo42dcdfd2021-10-19 17:34:12 -04004528func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004529 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4530 if err != nil || pgClient == nil {
4531 return err
4532 }
4533 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4534 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004535 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004536 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004537 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4538 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004539 if status.Code(err) == codes.Unavailable {
4540 dh.setOltAvailable(false)
4541 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004542 logger.Errorw(ctx, "omci-failure",
4543 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004544 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004545 }
4546 return err
4547}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004548
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004549func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4550 // Check if there are additional TCONT instances necessary/available
4551 pDevEntry.MutexPersOnuConfig.Lock()
4552 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4553 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4554 pDevEntry.MutexPersOnuConfig.Unlock()
4555 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4556 logger.Debugw(ctx, "checking available TCONT instances",
4557 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4558 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4559 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4560 log.Fields{"device-id": dh.device.Id})
4561 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304562 return fmt.Errorf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004563 }
4564 } else {
4565 pDevEntry.MutexPersOnuConfig.Unlock()
4566 }
4567 // Check if there are enough PrioQueue instances available
4568 if dh.pOnuTP != nil {
4569 var numberOfUsPrioQueueDbInsts int
4570
4571 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4572 for _, mgmtEntityID := range queueInstKeys {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304573 if mgmtEntityID >= 0x8000 {
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004574 numberOfUsPrioQueueDbInsts++
4575 }
4576 }
4577 // Check if there is an upstream PriorityQueue instance available for each Gem port
4578 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4579 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4580 log.Fields{"device-id": dh.DeviceID,
4581 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4582 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4583 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4584
4585 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4586 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4587 log.Fields{"device-id": dh.device.Id})
4588 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05304589 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 +00004590 }
4591 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4592 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4593 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4594 } else {
4595 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4596 log.Fields{"device-id": dh.DeviceID})
4597 }
4598 return nil
4599}
4600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004601// GetDeviceID - TODO: add comment
4602func (dh *deviceHandler) GetDeviceID() string {
4603 return dh.DeviceID
4604}
4605
4606// GetProxyAddressID - TODO: add comment
4607func (dh *deviceHandler) GetProxyAddressID() string {
4608 return dh.device.ProxyAddress.GetDeviceId()
4609}
4610
4611// GetProxyAddressType - TODO: add comment
4612func (dh *deviceHandler) GetProxyAddressType() string {
4613 return dh.device.ProxyAddress.GetDeviceType()
4614}
4615
4616// GetProxyAddress - TODO: add comment
4617func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4618 return dh.device.ProxyAddress
4619}
4620
4621// GetEventProxy - TODO: add comment
4622func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4623 return dh.EventProxy
4624}
4625
4626// GetOmciTimeout - TODO: add comment
4627func (dh *deviceHandler) GetOmciTimeout() int {
4628 return dh.pOpenOnuAc.omciTimeout
4629}
4630
4631// GetAlarmAuditInterval - TODO: add comment
4632func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4633 return dh.pOpenOnuAc.alarmAuditInterval
4634}
4635
4636// GetDlToOnuTimeout4M - TODO: add comment
4637func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4638 return dh.pOpenOnuAc.dlToOnuTimeout4M
4639}
4640
4641// GetUniEntityMap - TODO: add comment
4642func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4643 return &dh.uniEntityMap
4644}
4645
4646// GetPonPortNumber - TODO: add comment
4647func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4648 return &dh.ponPortNumber
4649}
4650
4651// GetUniVlanConfigFsm - TODO: add comment
4652func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004653 dh.lockVlanConfig.RLock()
4654 value := dh.UniVlanConfigFsmMap[uniID]
4655 dh.lockVlanConfig.RUnlock()
4656 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004657}
4658
4659// GetOnuAlarmManager - TODO: add comment
4660func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4661 return dh.pAlarmMgr
4662}
4663
4664// GetOnuMetricsManager - TODO: add comment
4665func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4666 return dh.pOnuMetricsMgr
4667}
4668
4669// GetOnuTP - TODO: add comment
4670func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4671 return dh.pOnuTP
4672}
4673
4674// GetBackendPathPrefix - TODO: add comment
4675func (dh *deviceHandler) GetBackendPathPrefix() string {
4676 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4677}
4678
4679// GetOnuIndication - TODO: add comment
4680func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4681 return dh.pOnuIndication
4682}
4683
4684// RLockMutexDeletionInProgressFlag - TODO: add comment
4685func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4686 dh.mutexDeletionInProgressFlag.RLock()
4687}
4688
4689// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4690func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4691 dh.mutexDeletionInProgressFlag.RUnlock()
4692}
4693
4694// GetDeletionInProgress - TODO: add comment
4695func (dh *deviceHandler) GetDeletionInProgress() bool {
4696 return dh.deletionInProgress
4697}
4698
4699// GetPmConfigs - TODO: add comment
4700func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4701 return dh.pmConfigs
4702}
4703
4704// GetDeviceType - TODO: add comment
4705func (dh *deviceHandler) GetDeviceType() string {
4706 return dh.DeviceType
4707}
4708
4709// GetLogicalDeviceID - TODO: add comment
4710func (dh *deviceHandler) GetLogicalDeviceID() string {
4711 return dh.logicalDeviceID
4712}
4713
4714// GetDevice - TODO: add comment
4715func (dh *deviceHandler) GetDevice() *voltha.Device {
4716 return dh.device
4717}
4718
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004719func (dh *deviceHandler) setOltAvailable(value bool) {
4720 dh.mutexOltAvailable.Lock()
4721 dh.oltAvailable = value
4722 dh.mutexOltAvailable.Unlock()
4723}
4724
4725// IsOltAvailable - TODO: add comment
4726func (dh *deviceHandler) IsOltAvailable() bool {
4727 dh.mutexOltAvailable.RLock()
4728 defer dh.mutexOltAvailable.RUnlock()
4729 return dh.oltAvailable
4730}
4731
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004732// GetMetricsEnabled - TODO: add comment
4733func (dh *deviceHandler) GetMetricsEnabled() bool {
4734 return dh.pOpenOnuAc.MetricsEnabled
4735}
4736
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004737// GetExtendedOmciSupportEnabled - TODO: add comment
4738func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4739 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4740}
4741
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304742// GetExtendedOmciSupportEnabled - TODO: add comment
4743func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
4744 return dh.pOpenOnuAc.skipOnuConfig
4745}
4746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004747// InitPmConfigs - TODO: add comment
4748func (dh *deviceHandler) InitPmConfigs() {
4749 dh.pmConfigs = &voltha.PmConfigs{}
4750}
4751
4752// GetUniPortMask - TODO: add comment
4753func (dh *deviceHandler) GetUniPortMask() int {
4754 return dh.pOpenOnuAc.config.UniPortMask
4755}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004756
4757func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4758 tpPathFound := false
4759 for _, tpPath := range aTpPathMap {
4760 if tpPath != "" {
4761 tpPathFound = true
4762 }
4763 }
4764 return tpPathFound
4765}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004766
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304767func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4768 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4769 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4770 return resp
4771}
4772
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05304773func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
4774 return dh.deviceDeleteCommChan
4775}
4776
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004777// PrepareForGarbageCollection - remove references to prepare for garbage collection
4778func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4779 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4780
4781 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4782 // first let the objects rest for some time to give all asynchronously started
4783 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004784 time.Sleep(2 * time.Second)
4785
4786 if dh.pOnuOmciDevice != nil {
4787 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4788 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4789 // reset handling (even in future coding), request monitoring is canceled here one last time to
4790 // be sure that all corresponding go routines are terminated
4791 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4792 }
4793 }
4794 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004795
4796 if dh.pOnuTP != nil {
4797 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4798 }
4799 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004800 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4801 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004802 select {
4803 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4804 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4805 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4806 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004807 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004808 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004809 }
4810 if dh.pAlarmMgr != nil {
4811 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4812 }
4813 if dh.pSelfTestHdlr != nil {
4814 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4815 }
4816 if dh.pLockStateFsm != nil {
4817 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4818 }
4819 if dh.pUnlockStateFsm != nil {
4820 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4821 }
4822 if dh.pOnuUpradeFsm != nil {
4823 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4824 }
4825 if dh.pOnuOmciDevice != nil {
4826 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4827 }
4828 for k, v := range dh.UniVlanConfigFsmMap {
4829 v.PrepareForGarbageCollection(ctx, aDeviceID)
4830 delete(dh.UniVlanConfigFsmMap, k)
4831 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05304832 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004833 dh.pOnuOmciDevice = nil
4834 dh.pOnuTP = nil
4835 dh.pOnuMetricsMgr = nil
4836 dh.pAlarmMgr = nil
4837 dh.pSelfTestHdlr = nil
4838 dh.pLockStateFsm = nil
4839 dh.pUnlockStateFsm = nil
4840 dh.pOnuUpradeFsm = nil
4841}