blob: e2dfad7093f6aff65377ee5affcf66d3511cfdc9 [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
145 addFlow bool // if true flow to be added, else removed
146 flowItem *of.OfpFlowStats
147 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400148 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700149 respChan *chan error // channel to report the Flow handling error
150}
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 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000154 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155 DeviceType string
156 adminState string
157 device *voltha.Device
158 logicalDeviceID string
159 ProxyAddressID string
160 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530161 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000162 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163
khenaidoo7d3c5582021-08-11 18:09:44 -0400164 coreClient *vgrpc.Client
165 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000166
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800167 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400168 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800169
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000170 pOpenOnuAc *OpenONUAC
171 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530172 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000173 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000174 pOnuOmciDevice *mib.OnuDeviceEntry
175 pOnuTP *avcfg.OnuUniTechProf
176 pOnuMetricsMgr *pmmgr.OnuMetricsManager
177 pAlarmMgr *almgr.OnuAlarmManager
178 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000179 exitChannel chan int
180 lockDevice sync.RWMutex
181 pOnuIndication *oop.OnuIndication
182 deviceReason uint8
183 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000184 pLockStateFsm *uniprt.LockStateFsm
185 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 //flowMgr *OpenOltFlowMgr
188 //eventMgr *OpenOltEventMgr
189 //resourceMgr *rsrcMgr.OpenOltResourceMgr
190
191 //discOnus sync.Map
192 //onus sync.Map
193 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000194 collectorIsRunning bool
195 mutexCollectorFlag sync.RWMutex
196 stopCollector chan bool
197 alarmManagerIsRunning bool
198 mutextAlarmManagerFlag sync.RWMutex
199 stopAlarmManager chan bool
200 stopHeartbeatCheck chan bool
201 uniEntityMap cmn.OnuUniPortMap
202 mutexKvStoreContext sync.Mutex
203 lockVlanConfig sync.RWMutex
204 lockVlanAdd sync.RWMutex
205 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
206 lockUpgradeFsm sync.RWMutex
207 pOnuUpradeFsm *swupg.OnuUpgradeFsm
208 upgradeCanceled bool
209 reconciling uint8
210 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000211 reconcilingFirstPass bool
212 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000213 reconcilingReasonUpdate bool
214 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000215 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
216 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
217 reconcileExpiryComplete time.Duration
218 reconcileExpiryVlanConfig time.Duration
219 mutexReadyForOmciConfig sync.RWMutex
220 readyForOmciConfig bool
221 deletionInProgress bool
222 mutexDeletionInProgressFlag sync.RWMutex
223 pLastUpgradeImageState *voltha.ImageState
224 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700225
226 flowCbChan []chan FlowCb
227 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300228 mutexForDisableDeviceRequested sync.RWMutex
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000229 mutexOltAvailable sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700230 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
231 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300232 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000233 oltAvailable bool
praneeth nalmasf405e962023-08-07 15:02:03 +0530234 deviceDeleteCommChan chan bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235}
236
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530237// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400238func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400240 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000241 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400242 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000244 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 dh.DeviceType = cloned.Type
246 dh.adminState = "up"
247 dh.device = cloned
248 dh.pOpenOnuAc = adapter
249 dh.exitChannel = make(chan int, 1)
250 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000251 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000252 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530254 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530255 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopHeartbeatCheck = make(chan bool, 2)
257 //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 +0000258 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000260 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000261 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000262 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300263 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000264 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000265 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000266 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000267 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300268 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000269 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000270 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000271 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
272 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
273 if rECSeconds < 2 {
274 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
275 rECSeconds = 2
276 }
277 rEVCSeconds := rECSeconds / 2
278 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000279 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000280 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000281 dh.pLastUpgradeImageState = &voltha.ImageState{
282 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
283 Reason: voltha.ImageState_UNKNOWN_ERROR,
284 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
285 }
286 dh.upgradeFsmChan = make(chan struct{})
praneeth nalmasf405e962023-08-07 15:02:03 +0530287 dh.deviceDeleteCommChan = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800289 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
290 dh.pmConfigs = cloned.PmConfigs
291 } /* else {
292 // will be populated when onu_metrics_mananger is initialized.
293 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800294
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 // Device related state machine
296 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000299 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
300 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
301 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
302 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
303 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 },
305 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000306 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
307 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
308 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
309 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
310 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
311 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
312 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
313 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314 },
315 )
mpagenkoaf801632020-07-03 10:00:42 +0000316
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317 return &dh
318}
319
Himani Chawla6d2ae152020-09-02 13:11:20 +0530320// start save the device to the data model
321func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000322 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000324 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325}
326
Himani Chawla4d908332020-08-31 12:30:20 +0530327/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530329func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330 logger.Debug("stopping-device-handler")
331 dh.exitChannel <- 1
332}
Himani Chawla4d908332020-08-31 12:30:20 +0530333*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334
335// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530336// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000337
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530338// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530339func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400340 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000341
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000342 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
praneeth.nalmas2d75f002023-03-31 12:59:59 +0530343
mpagenko1cc3cb42020-07-27 15:24:38 +0000344 if dh.pDeviceStateFsm.Is(devStNull) {
345 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000346 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 +0000347 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000348 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800349 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
350 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800351 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400352 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000353 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800354 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800355 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000356 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000358 }
359
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000360}
361
khenaidoo42dcdfd2021-10-19 17:34:12 -0400362func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000363 /* 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 +0530364 //assuming omci message content is hex coded!
365 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000367 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000368 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530370 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000371 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000372 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000373 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000374 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
375 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000377 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
378 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530379}
380
khenaidoo42dcdfd2021-10-19 17:34:12 -0400381func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000383
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
387 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 if dh.pOnuTP == nil {
390 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 log.Fields{"device-id": dh.DeviceID})
393 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000395 if !dh.IsReadyForOmciConfig() {
396 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
397 "device-state": dh.GetDeviceReasonString()})
398 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000400 //previous state test here was just this one, now extended for more states to reject the SetRequest:
401 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
402 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530403
Himani Chawla26e555c2020-08-31 12:30:20 +0530404 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
406 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 dh.pOnuTP.LockTpProcMutex()
408 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409
mpagenko44bd8362021-11-15 11:40:05 +0000410 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000411 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 }
414 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000415 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800416 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000417 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
418 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800419 return err
420 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000421 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
422 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000424 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530425
Girish Gowdra50e56422021-06-01 16:46:04 -0700426 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400427 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000428 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
429 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000430
431 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
432 if err != nil {
433 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
434 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
435 // stopping all further processing
436 _ = dh.UpdateInterface(ctx)
437 return err
438 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 // if there has been some change for some uni TechProfilePath
440 //in order to allow concurrent calls to other dh instances we do not wait for execution here
441 //but doing so we can not indicate problems to the caller (who does what with that then?)
442 //by now we just assume straightforward successful execution
443 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
444 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530445
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 // deadline context to ensure completion of background routines waited for
447 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
448 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
449 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000450
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700452
453 var wg sync.WaitGroup
454 wg.Add(1) // for the 1 go routine to finish
455 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700457 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
459 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 -0700460 return tpErr
461 }
462 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
463 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000464 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700465 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000466 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700467 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
469 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.DeviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700470 return kvErr
471 }
472 return nil
473 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000474 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700475 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700476 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530477 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000479 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
480 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 return nil
482}
483
khenaidoo42dcdfd2021-10-19 17:34:12 -0400484func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000485 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530486
487 if dh.pOnuTP == nil {
488 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 log.Fields{"device-id": dh.DeviceID})
491 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530492 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000494 dh.pOnuTP.LockTpProcMutex()
495 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530496
mpagenko0f543222021-11-03 16:24:14 +0000497 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
498 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
499 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502 }
503 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000504 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000506 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
507 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 return err
509 }
mpagenko0f543222021-11-03 16:24:14 +0000510 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
511 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000512 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
Mahir Gunyel9545be22021-07-04 15:53:16 -0700514 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000515 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000516
Himani Chawla26e555c2020-08-31 12:30:20 +0530517}
518
khenaidoo42dcdfd2021-10-19 17:34:12 -0400519func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000520 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000521
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
525 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530527 if dh.pOnuTP == nil {
528 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000529 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000530 log.Fields{"device-id": dh.DeviceID})
531 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 }
533
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 dh.pOnuTP.LockTpProcMutex()
536 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000537
mpagenko0f543222021-11-03 16:24:14 +0000538 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
539 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
540 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000542 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000543 }
544 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700545 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800547 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000548 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
549 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800550 return err
551 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530553
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000554 var wg sync.WaitGroup
555 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
556 dctx, cancel := context.WithDeadline(context.Background(), deadline)
557 wg.Add(1)
558 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
559 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
560 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
561 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
562 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
563 return err
564 }
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 var wg2 sync.WaitGroup
606 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
607 wg2.Add(1)
608 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000609 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700611 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
613 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700614 return err
615 }
616 }
617 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700619 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530620 return nil
621}
622
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530623// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000624func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400625 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400626 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700627 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
628 var errorsList []error
629 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000630 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000631 if apOfFlowChanges.ToRemove != nil {
632 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000633 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000635 "device-id": dh.DeviceID})
636 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700637 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000638 continue
639 }
640 flowInPort := flow.GetInPort(flowItem)
641 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
643 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700644 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000645 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000647 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000648 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000651 continue
652 } else {
653 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000654 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000655 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
656 loUniPort = uniPort
657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000660 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700662 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000663 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000664 }
665 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000666 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000667 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
668 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700669
670 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
671 // Step1 : Fill flowControlBlock
672 // Step2 : Push the flowControlBlock to ONU channel
673 // Step3 : Wait on response channel for response
674 // Step4 : Return error value
675 startTime := time.Now()
676 respChan := make(chan error)
677 flowCb := FlowCb{
678 ctx: ctx,
679 addFlow: false,
680 flowItem: flowItem,
681 flowMetaData: nil,
682 uniPort: loUniPort,
683 respChan: &respChan,
684 }
685 dh.flowCbChan[loUniPort.UniID] <- flowCb
686 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
687 // Wait on the channel for flow handlers return value
688 retError = <-respChan
689 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
690 if retError != nil {
691 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
692 log.Fields{"device-id": dh.DeviceID, "error": retError})
693 errorsList = append(errorsList, retError)
694 continue
695 }
696 } else {
697 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
698 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000699 }
700 }
701 }
702 }
mpagenko01e726e2020-10-23 09:45:29 +0000703 if apOfFlowChanges.ToAdd != nil {
704 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
705 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000707 "device-id": dh.DeviceID})
708 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700709 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000710 continue
711 }
712 flowInPort := flow.GetInPort(flowItem)
713 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
715 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700716 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000717 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000718 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000719 } else if flowInPort == dh.ponPortNumber {
720 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000722 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000723 continue
724 } else {
725 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000726 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000727 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
728 loUniPort = uniPort
729 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000730 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000732 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000733 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700734 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000735 continue
mpagenko01e726e2020-10-23 09:45:29 +0000736 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000737 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
738 // if not, we just throw some error here to have an indication about that, if we really need to support that
739 // then we would need to create some means to activate the internal stored flows
740 // after the device gets active automatically (and still with its dependency to the TechProfile)
741 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
742 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000743 if !dh.IsReadyForOmciConfig() {
744 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
745 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700746 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
747 errorsList = append(errorsList, retError)
748 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 }
750
mpagenko01e726e2020-10-23 09:45:29 +0000751 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000753 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
754 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700755 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
756 // Step1 : Fill flowControlBlock
757 // Step2 : Push the flowControlBlock to ONU channel
758 // Step3 : Wait on response channel for response
759 // Step4 : Return error value
760 startTime := time.Now()
761 respChan := make(chan error)
762 flowCb := FlowCb{
763 ctx: ctx,
764 addFlow: true,
765 flowItem: flowItem,
766 flowMetaData: apFlowMetaData,
767 uniPort: loUniPort,
768 respChan: &respChan,
769 }
770 dh.flowCbChan[loUniPort.UniID] <- flowCb
771 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
772 // Wait on the channel for flow handlers return value
773 retError = <-respChan
774 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
775 if retError != nil {
776 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
777 log.Fields{"device-id": dh.DeviceID, "error": retError})
778 errorsList = append(errorsList, retError)
779 continue
780 }
781 } else {
782 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
783 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000784 }
785 }
786 }
787 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700788 if len(errorsList) > 0 {
789 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
790 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
791 }
792 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000793}
794
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530795// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
796// following are the expected device states after this activity:
797// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000798// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
800 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300801 dh.mutexForDisableDeviceRequested.Lock()
802 dh.disableDeviceRequested = true
803 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000804 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000805 //note that disableDevice sequences in some 'ONU active' state may yield also
806 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000807 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000809 //disable-device shall be just a UNi/ONU-G related admin state setting
810 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000811
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000813 // disable UNI ports/ONU
814 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
815 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000816 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000817 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000820 }
821 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000822 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000824 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400825 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000826 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000827 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400828 OperStatus: voltha.OperStatus_UNKNOWN,
829 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000830 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000832 }
mpagenko01e726e2020-10-23 09:45:29 +0000833 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000834
835 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000836 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000837 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300838 }
839}
840
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530841// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
843 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000844
mpagenkoaa3afe92021-05-21 16:20:58 +0000845 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000846 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
847 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
848 // for real ONU's that should have nearly no influence
849 // Note that for real ONU's there is anyway a problematic situation with following sequence:
850 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
851 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
852 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000854
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000855 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300857 dh.mutexForDisableDeviceRequested.Lock()
858 dh.disableDeviceRequested = false
859 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000860 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000862 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000865 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300866}
867
dbainbri4d3a0dc2020-12-02 00:33:42 +0000868func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530869 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000872 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000874 return
875 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000877 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000879 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000881 }
mpagenko101ac942021-11-16 15:01:29 +0000882 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000883 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000884 }
Himani Chawla4d908332020-08-31 12:30:20 +0530885 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000886 pDevEntry.MutexPersOnuConfig.RLock()
887 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
888 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
889 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
890 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
891 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000893}
894
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000895func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530896 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000897
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000898 continueWithFlowConfig := false
899
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000900 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000901 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000902 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000903 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
904 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 dh.pOnuTP.LockTpProcMutex()
907 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000908
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000910 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
912 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530913 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000915 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
916 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000917 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700919 techProfsFound := false
920 techProfInstLoadFailed := false
921outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000922 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000923 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000924 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000925 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000927 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000928 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000929 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
931 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000932 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000933 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000934 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700935 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 var iaTechTpInst ia.TechProfileDownloadMessage
937 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800938 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000939 pDevEntry.MutexReconciledTpInstances.RLock()
940 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
941 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000942 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000943 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000945 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700946 break outerLoop
947 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000948 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000949 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 var tpInst tech_profile.TechProfileInstance
951 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400952 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000954 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000957 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700959 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
960 break outerLoop
961 }
962
Girish Gowdra041dcb32020-11-16 16:54:30 -0800963 // deadline context to ensure completion of background routines waited for
964 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
965 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000967
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800969 var wg sync.WaitGroup
970 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000972 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
974 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700975 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
976 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800977 }
mpagenko2dc896e2021-08-02 12:03:59 +0000978 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 if len(uniData.PersFlowParams) != 0 {
980 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000981 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000983 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 } // for all UNI entries from SOnuPersistentData
985 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
986 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000987 }
mpagenko2dc896e2021-08-02 12:03:59 +0000988
989 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
990 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000991
992 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000993}
994
995func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
996 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
997 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530998 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001000 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 return
1002 }
mpagenko2dc896e2021-08-02 12:03:59 +00001003 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001004 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001005 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001006 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001007 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001008 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009 }
mpagenko2dc896e2021-08-02 12:03:59 +00001010 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301011 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001013 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001014 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015}
1016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1018 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001020 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001021 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001022 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001023 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001024 return
1025 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001026
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001027 pDevEntry.MutexPersOnuConfig.RLock()
1028 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1029 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301030 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001032 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001033 return
1034 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001035 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001036 var uniVlanConfigEntries []uint8
1037 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001040 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1041 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001044 continue
1045 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001046 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001047 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001048 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001049 // It doesn't make sense to configure any flows if no TPs are available
1050 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001051 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1053 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001054 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001056
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001059 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001060 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001061 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1062 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001063 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064 return
1065 }
mpagenko101ac942021-11-16 15:01:29 +00001066 //needed to split up function due to sca complexity
1067 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1068
mpagenko2dc896e2021-08-02 12:03:59 +00001069 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001070 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001071 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1072 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001073 // this can't be used as global finished reconciling flag because
1074 // assumes is getting called before the state machines for the last flow is completed,
1075 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001076 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1077 } // for all UNI entries from SOnuPersistentData
1078 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001079
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001080 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301081 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001083 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001084 return
1085 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001086 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1087 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1088 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1089 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1090 log.Fields{"device-id": dh.DeviceID})
1091 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1092 if pDevEntry != nil {
1093 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001094 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001095 } else {
1096 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1097 log.Fields{"device-id": dh.DeviceID})
1098 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1099 if pDevEntry != nil {
1100 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1101 }
1102 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001103 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001104 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001105}
1106
mpagenko101ac942021-11-16 15:01:29 +00001107func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1108 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1109 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1110 flowsProcessed := 0
1111 lastFlowToReconcile := false
1112 loUniID := apUniPort.UniID
1113 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001114 if !(*apFlowsFound) {
1115 *apFlowsFound = true
1116 syncChannel := make(chan struct{})
1117 // start go routine with select() on reconciling vlan config channel before
1118 // starting vlan config reconciling process to prevent loss of any signal
1119 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1120 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1121 //block until the wait routine is really blocked on channel input
1122 // in order to prevent to early ready signal from VlanConfig processing
1123 <-syncChannel
1124 }
1125 if flowsProcessed == len(aPersFlowParam)-1 {
1126 var uniAdded bool
1127 lastFlowToReconcile = true
1128 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1129 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001130 }
1131 }
mpagenko101ac942021-11-16 15:01:29 +00001132 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1133 "device-id": dh.DeviceID, "uni-id": loUniID,
1134 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1135 dh.lockVlanConfig.Lock()
1136 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1137 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1138 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301139 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 +00001140 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1141 }
1142 } else {
1143 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301144 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301145 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001146 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1147 }
1148 }
1149 dh.lockVlanConfig.Unlock()
1150 flowsProcessed++
1151 } //for all flows of this UNI
1152}
1153
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301154// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1155//
1156// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001157func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1158 waitGroup *cmn.WaitGroupWithTimeOut) {
1159 var reconciledUniVlanConfigEntries []uint8
1160 var appended bool
1161 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1162 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1163 "device-id": dh.DeviceID, "expiry": expiry})
1164 // indicate blocking on channel now to the caller
1165 aSyncChannel <- struct{}{}
1166 for {
1167 select {
1168 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1169 switch uniIndication {
1170 // no activity requested (should normally not be received) - just continue waiting
1171 case cWaitReconcileFlowNoActivity:
1172 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1173 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301174 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001175 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1176 return
1177 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1178 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301179 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001180 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1181 return
1182 // this should be a valid UNI vlan config done indication
1183 default:
1184 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301185 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001186 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1187 if reconciledUniVlanConfigEntries, appended =
1188 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1189 waitGroup.Done()
1190 }
1191 } else {
1192 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1193 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1194 }
1195 } //switch uniIndication
1196
1197 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1198 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1199 log.Fields{"device-id": dh.DeviceID})
1200 return
1201 }
1202 }
1203}
1204
1205func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1206 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1207}
1208
1209func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1210 for _, ele := range slice {
1211 if ele == val {
1212 return slice, false
1213 }
1214 }
1215 return append(slice, val), true
1216}
1217
1218// sendChReconcileFinished - sends true or false on reconcileFinish channel
1219func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1220 if dh != nil { //if the object still exists (might have been already deleted in background)
1221 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1222 select {
1223 case dh.chReconcilingFinished <- success:
1224 default:
1225 }
1226 }
1227}
1228
1229// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1230func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1231 if dh != nil { //if the object still exists (might have been already deleted in background)
1232 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1233 select {
1234 case dh.chUniVlanConfigReconcilingDone <- value:
1235 default:
1236 }
1237 }
1238}
1239
dbainbri4d3a0dc2020-12-02 00:33:42 +00001240func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001242
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001243 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001244 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001245 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001247 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001248 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001249
1250 // deadline context to ensure completion of background routines waited for
1251 //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 +05301252 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001254
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001256
1257 var wg sync.WaitGroup
1258 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001261
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001262 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001264}
1265
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301266// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001267// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301268//
1269// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1270//
1271// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001272func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001273 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001274 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001275 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001276 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001277 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301279 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001281 return
Himani Chawla4d908332020-08-31 12:30:20 +05301282 }
mpagenko01e726e2020-10-23 09:45:29 +00001283
1284 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001286
mpagenko44bd8362021-11-15 11:40:05 +00001287 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001289 // 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 -04001290 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001291 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001292 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001293 OperStatus: voltha.OperStatus_DISCOVERED,
1294 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001295 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001297 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001298 }
mpagenkoe4782082021-11-25 12:04:26 +00001299 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001300 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001301 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001303 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1304 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1305 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1306 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001307}
1308
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301309// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1310//
1311// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001312func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001314 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001315 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001316
1317 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001319 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1321 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001322 }
1323
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001325 var inactiveImageID uint16
1326 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1327 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001328 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1329 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001330 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001331 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001332 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001333 if err == nil {
1334 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1335 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001337 }
1338 } else {
1339 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001340 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001341 }
mpagenko15ff4a52021-03-02 10:09:20 +00001342 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001343 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001345 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1346 dh.upgradeCanceled = true
1347 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1348 }
mpagenko38662d02021-08-11 09:45:19 +00001349 //no effort spent anymore for the old API to automatically cancel and restart the download
1350 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001351 }
mpagenko15ff4a52021-03-02 10:09:20 +00001352 } else {
1353 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001355 }
1356 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1358 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001359 }
1360 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001361}
1362
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301363// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001364// after the OnuImage has been downloaded to the adapter, called in background
1365func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001367
1368 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001369 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001370 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001372 return
1373 }
1374
1375 var inactiveImageID uint16
1376 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1377 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001378 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001379
mpagenko59862f02021-10-11 08:53:18 +00001380 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001382 // but must be still locked at calling createOnuUpgradeFsm
1383 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1384 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1385 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001386 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1387 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001389 //flush the remove upgradeFsmChan channel
1390 select {
1391 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001392 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001393 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001394 }
mpagenko59862f02021-10-11 08:53:18 +00001395 dh.lockUpgradeFsm.Unlock()
1396 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1397 dh.upgradeCanceled = true
1398 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1399 }
mpagenko38662d02021-08-11 09:45:19 +00001400 select {
1401 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001403 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1404 return
1405 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001406 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001407 }
mpagenko59862f02021-10-11 08:53:18 +00001408 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001409 }
mpagenko38662d02021-08-11 09:45:19 +00001410
1411 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001412 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001413 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001414 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001415 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001416 if err == nil {
1417 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1418 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1419 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001421 return
1422 }
mpagenko38662d02021-08-11 09:45:19 +00001423 } else {
1424 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001425 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001426 }
1427 return
1428 }
1429 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001431}
1432
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301433// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001434func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1435 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001436 var err error
1437 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1438 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1439 // 2.) activation of the inactive image
1440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001442 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001443 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1444 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001445 }
1446 dh.lockUpgradeFsm.RLock()
1447 if dh.pOnuUpradeFsm != nil {
1448 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001449 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001450 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001451 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1452 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001453 }
mpagenko59862f02021-10-11 08:53:18 +00001454 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1455 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1456 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1457 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001458 // use the OnuVendor identification from this device for the internal unique name
1459 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001460 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001461 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001462 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001463 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464 "device-id": dh.DeviceID, "error": err})
1465 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001466 }
mpagenko183647c2021-06-08 15:25:04 +00001467 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001469 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001470 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001471 } //else
1472 dh.lockUpgradeFsm.RUnlock()
1473
1474 // 2.) check if requested image-version equals the inactive one and start its activation
1475 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1476 var inactiveImageID uint16
1477 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1478 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001479 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1480 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001481 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001482 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001483 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001484 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001485 if err == nil {
1486 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1487 inactiveImageID, aCommitRequest); err != nil {
1488 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 "device-id": dh.DeviceID, "error": err})
1490 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001491 }
1492 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001493 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001494 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001495 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001496 } //else
1497 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 "device-id": dh.DeviceID, "error": err})
1499 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001500}
1501
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301502// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001503func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1504 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001505 var err error
1506 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1507 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1508 // 2.) commitment of the active image
1509
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001510 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001511 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001512 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1513 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001514 }
1515 dh.lockUpgradeFsm.RLock()
1516 if dh.pOnuUpradeFsm != nil {
1517 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001519 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001520 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1521 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001522 }
mpagenko59862f02021-10-11 08:53:18 +00001523 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1524 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1525 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1526 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001527 // use the OnuVendor identification from this device for the internal unique name
1528 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001529 // 1.) check a started upgrade process and relay the commitment request to it
1530 // the running upgrade may be based either on the imageIdentifier (started from download)
1531 // or on the imageVersion (started from pure activation)
1532 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1533 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 "device-id": dh.DeviceID, "error": err})
1536 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001537 }
mpagenko183647c2021-06-08 15:25:04 +00001538 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001539 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001540 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001541 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001542 } //else
1543 dh.lockUpgradeFsm.RUnlock()
1544
mpagenko183647c2021-06-08 15:25:04 +00001545 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001546 var activeImageID uint16
1547 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1548 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001549 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1550 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001551 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001552 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001553 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001554 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001555 if err == nil {
1556 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1557 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001558 "device-id": dh.DeviceID, "error": err})
1559 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001560 }
1561 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001562 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001563 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001564 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001565 } //else
1566 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001567 "device-id": dh.DeviceID, "error": err})
1568 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001569}
1570
mpagenkoaa3afe92021-05-21 16:20:58 +00001571func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001572 aVersion string) *voltha.ImageState {
1573 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001574 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001575 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001576 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001577 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1578 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1579 if aVersion == dh.pLastUpgradeImageState.Version {
1580 pImageState = dh.pLastUpgradeImageState
1581 } else { //state request for an image version different from last processed image version
1582 pImageState = &voltha.ImageState{
1583 Version: aVersion,
1584 //we cannot state something concerning this version
1585 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1586 Reason: voltha.ImageState_NO_ERROR,
1587 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1588 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001589 }
1590 }
mpagenko38662d02021-08-11 09:45:19 +00001591 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001592}
1593
1594func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1595 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001596 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001597 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001598 dh.lockUpgradeFsm.RLock()
1599 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001600 dh.lockUpgradeFsm.RUnlock()
1601 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001602 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001603 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1604 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1605 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1606 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1607 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1608 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001609 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1610 dh.upgradeCanceled = true
1611 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1612 }
mpagenko45586762021-10-01 08:30:22 +00001613 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001614 } else {
mpagenko45586762021-10-01 08:30:22 +00001615 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001616 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1617 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1618 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1619 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1620 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1621 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001622 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1623 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001624 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1625 //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 +00001626 }
1627}
1628
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001629func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1630
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001632
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001634 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1636 pDevEntry.MutexOnuImageStatus.Lock()
1637 pDevEntry.POnuImageStatus = onuImageStatus
1638 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001639
1640 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001642 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1643 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1645 pDevEntry.MutexOnuImageStatus.Lock()
1646 pDevEntry.POnuImageStatus = nil
1647 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001648 return images, err
1649}
1650
Himani Chawla6d2ae152020-09-02 13:11:20 +05301651// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652// #####################################################################################
1653
1654// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301655// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001658 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1659 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660}
1661
1662// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001665 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666 var err error
1667
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668 // populate what we know. rest comes later after mib sync
1669 dh.device.Root = false
1670 dh.device.Vendor = "OpenONU"
1671 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001672 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001673 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001674
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001676
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 if !dh.IsReconciling() {
1678 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001679 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1680 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1681 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301682 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001683 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301684 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001686 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687
Himani Chawla4d908332020-08-31 12:30:20 +05301688 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001689 dh.ponPortNumber = dh.device.ParentPortNo
1690
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1692 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1693 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301696 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001697
1698 /*
1699 self._pon = PonPort.create(self, self._pon_port_number)
1700 self._pon.add_peer(self.parent_id, self._pon_port_number)
1701 self.logger.debug('adding-pon-port-to-agent',
1702 type=self._pon.get_port().type,
1703 admin_state=self._pon.get_port().admin_state,
1704 oper_status=self._pon.get_port().oper_status,
1705 )
1706 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001707 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301708 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001709 var ponPortNo uint32 = 1
1710 if dh.ponPortNumber != 0 {
1711 ponPortNo = dh.ponPortNumber
1712 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001713
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001714 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001715 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001716 PortNo: ponPortNo,
1717 Label: fmt.Sprintf("pon-%d", ponPortNo),
1718 Type: voltha.Port_PON_ONU,
1719 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301720 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001721 PortNo: ponPortNo}}, // Peer port is parent's port number
1722 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001723 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001724 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001725 e.Cancel(err)
1726 return
1727 }
1728 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301729 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001730 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001731 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001732}
1733
1734// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001736
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001737 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001738 var err error
1739 /*
1740 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1741 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1742 return nil
1743 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001745 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001746 e.Cancel(err)
1747 return
1748 }
1749
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001750 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001752 // reconcilement will be continued after mib download is done
1753 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001754
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001755 /*
1756 ############################################################################
1757 # Setup Alarm handler
1758 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1759 device.serial_number)
1760 ############################################################################
1761 # Setup PM configuration for this device
1762 # Pass in ONU specific options
1763 kwargs = {
1764 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1765 'heartbeat': self.heartbeat,
1766 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1767 }
1768 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1769 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1770 self.logical_device_id, device.serial_number,
1771 grouped=True, freq_override=False, **kwargs)
1772 pm_config = self._pm_metrics.make_proto()
1773 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1774 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1775 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1776
1777 # Note, ONU ID and UNI intf set in add_uni_port method
1778 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1779 ani_ports=[self._pon])
1780
1781 # Code to Run OMCI Test Action
1782 kwargs_omci_test_action = {
1783 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1784 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1785 }
1786 serial_number = device.serial_number
1787 self._test_request = OmciTestRequest(self.core_proxy,
1788 self.omci_agent, self.device_id,
1789 AniG, serial_number,
1790 self.logical_device_id,
1791 exclusive=False,
1792 **kwargs_omci_test_action)
1793
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001794 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001795 else:
1796 self.logger.info('onu-already-activated')
1797 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001798
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001799 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800}
1801
1802// doStateConnected get the device info and update to voltha core
1803// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301804//
1805// voltha-openolt-adapter/adaptercore/device_handler.go
1806// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001808
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001809 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301810 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001811 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001812 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001813}
1814
1815// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001818 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301819 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001821 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001822
1823 /*
1824 // Synchronous call to update device state - this method is run in its own go routine
1825 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1826 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001827 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 +00001828 return err
1829 }
1830 return nil
1831 */
1832}
1833
1834// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001837 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001838 var err error
1839
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001840 device := dh.device
1841 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001843 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001844 e.Cancel(err)
1845 return
1846 }
1847
1848 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001850 /*
1851 // Update the all ports state on that device to disable
1852 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001853 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854 return er
1855 }
1856
1857 //Update the device oper state and connection status
1858 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1859 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1860 dh.device = cloned
1861
1862 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001863 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001864 return er
1865 }
1866
1867 //get the child device for the parent device
1868 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1869 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001870 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 return err
1872 }
1873 for _, onuDevice := range onuDevices.Items {
1874
1875 // Update onu state as down in onu adapter
1876 onuInd := oop.OnuIndication{}
1877 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001878 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001879 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1880 if er != nil {
1881 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001882 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883 //Do not return here and continue to process other ONUs
1884 }
1885 }
1886 // * Discovered ONUs entries need to be cleared , since after OLT
1887 // is up, it starts sending discovery indications again* /
1888 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001889 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001890 return nil
1891 */
Himani Chawla4d908332020-08-31 12:30:20 +05301892 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001893 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001894 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001895}
1896
Himani Chawla6d2ae152020-09-02 13:11:20 +05301897// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001898// #################################################################################
1899
1900// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301901// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301903// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001904func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001905 dh.lockDevice.RLock()
1906 pOnuDeviceEntry := dh.pOnuOmciDevice
1907 if aWait && pOnuDeviceEntry == nil {
1908 //keep the read sema short to allow for subsequent write
1909 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001910 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001911 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1912 // so it might be needed to wait here for that event with some timeout
1913 select {
1914 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001915 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001916 return nil
1917 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001919 // if written now, we can return the written value without sema
1920 return dh.pOnuOmciDevice
1921 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922 }
mpagenko3af1f032020-06-10 08:53:41 +00001923 dh.lockDevice.RUnlock()
1924 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001925}
1926
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301927// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001928func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1929 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001930 dh.lockDevice.Lock()
1931 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001932 dh.pOnuOmciDevice = apDeviceEntry
1933 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001934 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301935 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001936 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001937}
1938
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301939// addOnuDeviceEntry creates a new ONU device or returns the existing
Himani Chawla6d2ae152020-09-02 13:11:20 +05301940func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001942
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001943 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001944 if deviceEntry == nil {
1945 /* costum_me_map in python code seems always to be None,
1946 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1947 /* also no 'clock' argument - usage open ...*/
1948 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001949 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1950 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1951 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1952 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1953 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001954 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001956 // fire deviceEntry ready event to spread to possibly waiting processing
1957 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001958 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001959 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001961 }
1962 // might be updated with some error handling !!!
1963 return nil
1964}
1965
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001967 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001968 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1969
1970 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001971
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001973 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1975 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001976 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05301977
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001978 if !dh.IsReconciling() {
1979 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001981 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001982 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001984 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001985
khenaidoo42dcdfd2021-10-19 17:34:12 -04001986 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001987 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001988 OperStatus: voltha.OperStatus_ACTIVATING,
1989 ConnStatus: voltha.ConnectStatus_REACHABLE,
1990 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001991 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001993 }
1994 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301995 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001996 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001998 pDevEntry.MutexPersOnuConfig.RLock()
1999 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
2000 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 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 +00002002 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00002003 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302004
2005 //VOL-4965: Recover previously Activating ONU during reconciliation.
2006 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
2007 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
2008 log.Fields{"device-id": dh.DeviceID})
2009 pDevEntry.MutexPersOnuConfig.Lock()
2010 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2011 pDevEntry.MutexPersOnuConfig.Unlock()
2012 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002013 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002014 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002015 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002016 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002017 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2018 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2019 // 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 +00002020 // 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 +00002021 // so let's just try to keep it simple ...
2022 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002024 if err != nil || device == nil {
2025 //TODO: needs to handle error scenarios
2026 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2027 return errors.New("Voltha Device not found")
2028 }
2029 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002030
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002031 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002032 return err
mpagenko3af1f032020-06-10 08:53:41 +00002033 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002034 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302035 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2036 /* this might be a good time for Omci Verify message? */
2037 verifyExec := make(chan bool)
2038 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2039 dh.device.Id, pDevEntry.PDevOmciCC, false,
2040 true, true) //exclusive and allowFailure (anyway not yet checked)
2041 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002042
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302043 /* give the handler some time here to wait for the OMCi verification result
2044 after Timeout start and try MibUpload FSM anyway
2045 (to prevent stopping on just not supported OMCI verification from ONU) */
2046 select {
2047 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2048 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2049 case testresult := <-verifyExec:
2050 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2051 case <-dh.deviceDeleteCommChan:
2052 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2053 return nil
2054 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002055 }
2056
2057 /* In py code it looks earlier (on activate ..)
2058 # Code to Run OMCI Test Action
2059 kwargs_omci_test_action = {
2060 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2061 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2062 }
2063 serial_number = device.serial_number
2064 self._test_request = OmciTestRequest(self.core_proxy,
2065 self.omci_agent, self.device_id,
2066 AniG, serial_number,
2067 self.logical_device_id,
2068 exclusive=False,
2069 **kwargs_omci_test_action)
2070 ...
2071 # Start test requests after a brief pause
2072 if not self._test_request_started:
2073 self._test_request_started = True
2074 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2075 reactor.callLater(tststart, self._test_request.start_collector)
2076
2077 */
2078 /* which is then: in omci_test_request.py : */
2079 /*
2080 def start_collector(self, callback=None):
2081 """
2082 Start the collection loop for an adapter if the frequency > 0
2083
2084 :param callback: (callable) Function to call to collect PM data
2085 """
2086 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2087 if callback is None:
2088 callback = self.perform_test_omci
2089
2090 if self.lc is None:
2091 self.lc = LoopingCall(callback)
2092
2093 if self.default_freq > 0:
2094 self.lc.start(interval=self.default_freq / 10)
2095
2096 def perform_test_omci(self):
2097 """
2098 Perform the initial test request
2099 """
2100 ani_g_entities = self._device.configuration.ani_g_entities
2101 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2102 is not None else None
2103 self._entity_id = ani_g_entities_ids[0]
2104 self.logger.info('perform-test', entity_class=self._entity_class,
2105 entity_id=self._entity_id)
2106 try:
2107 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2108 result = yield self._device.omci_cc.send(frame)
2109 if not result.fields['omci_message'].fields['success_code']:
2110 self.logger.info('Self-Test Submitted Successfully',
2111 code=result.fields[
2112 'omci_message'].fields['success_code'])
2113 else:
2114 raise TestFailure('Test Failure: {}'.format(
2115 result.fields['omci_message'].fields['success_code']))
2116 except TimeoutError as e:
2117 self.deferred.errback(failure.Failure(e))
2118
2119 except Exception as e:
2120 self.logger.exception('perform-test-Error', e=e,
2121 class_id=self._entity_class,
2122 entity_id=self._entity_id)
2123 self.deferred.errback(failure.Failure(e))
2124
2125 */
2126
2127 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002129
mpagenko1cc3cb42020-07-27 15:24:38 +00002130 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2131 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2132 * 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 +05302133 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002134 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002135 //call MibUploadFSM - transition up to state UlStInSync
2136 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002137 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002138 if pMibUlFsm.Is(mib.UlStDisabled) {
2139 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2140 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2141 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302142 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002143 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302144 //Determine ONU status and start/re-start MIB Synchronization tasks
2145 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002146 if pDevEntry.IsNewOnu() {
2147 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2148 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2149 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002150 }
Himani Chawla4d908332020-08-31 12:30:20 +05302151 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002152 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2153 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2154 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302155 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002156 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002157 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002158 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 "device-id": dh.DeviceID})
2161 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002162 }
2163 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002164 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2165 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002166 }
2167 return nil
2168}
2169
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002170func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002171 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002172 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302174 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002175
mpagenko900ee4b2020-10-12 11:56:34 +00002176 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2177 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2178 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002179 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002181 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002182 // abort: system behavior is just unstable ...
2183 return err
2184 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002185 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 _ = 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 +00002187
2188 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002189 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002190 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002191 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2193 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002194 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002196
2197 //TODO!!! remove existing traffic profiles
2198 /* from py code, if TP's exist, remove them - not yet implemented
2199 self._tp = dict()
2200 # Let TP download happen again
2201 for uni_id in self._tp_service_specific_task:
2202 self._tp_service_specific_task[uni_id].clear()
2203 for uni_id in self._tech_profile_download_done:
2204 self._tech_profile_download_done[uni_id].clear()
2205 */
2206
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002208
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002210
mpagenkoe4782082021-11-25 12:04:26 +00002211 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002212 // abort: system behavior is just unstable ...
2213 return err
2214 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002217 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002219 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2220 OperStatus: voltha.OperStatus_DISCOVERED,
2221 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002222 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002225 // abort: system behavior is just unstable ...
2226 return err
2227 }
2228 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002229 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002230 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002231 return nil
2232}
2233
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002234func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002235 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2236 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2237 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2238 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002239 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002240
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002241 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302242 //VOL-5260: During race conditions when adoptDevice has not yet completed
2243 // and deleteDevice is issued , returning error will further prevent clean up
2244 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002245 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302247 return nil
mpagenko900ee4b2020-10-12 11:56:34 +00002248 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002249 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002250 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002251 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002252 pDevEntry.MutexOnuImageStatus.RLock()
2253 if pDevEntry.POnuImageStatus != nil {
2254 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002255 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002256 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002257
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002258 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002259 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002260 }
2261 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002263 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002265 }
mpagenko101ac942021-11-16 15:01:29 +00002266 //stop any deviceHandler reconcile processing (if running)
2267 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002268 //port lock/unlock FSM's may be active
2269 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002270 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002271 }
2272 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002274 }
2275 //techProfile related PonAniConfigFsm FSM may be active
2276 if dh.pOnuTP != nil {
2277 // should always be the case here
2278 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002279 if dh.pOnuTP.PAniConfigFsm != nil {
2280 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2281 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002282 }
mpagenko900ee4b2020-10-12 11:56:34 +00002283 }
2284 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002285 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002286 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002287 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002288 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002289 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002290 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002291 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002292 } else {
2293 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002294 }
2295 }
2296 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302297
2298 dh.mutexCollectorFlag.Lock()
2299 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2300 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002301 // Stop collector routine
2302 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302303 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002304 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302305 dh.mutexCollectorFlag.Unlock()
2306
2307 dh.mutextAlarmManagerFlag.Lock()
2308 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2309 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302310 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302311 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302312 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302313 dh.mutextAlarmManagerFlag.Unlock()
2314
2315 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2316 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2317 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302319 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002320 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302321 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302322
Girish Gowdrae95687a2021-09-08 16:30:58 -07002323 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2324
mpagenko80622a52021-02-09 16:53:23 +00002325 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002327 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002328 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002329 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002330 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002331 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002332 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2333 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2334 // (even though it may also run into direct cancellation, a bit hard to verify here)
2335 // so don't set 'dh.upgradeCanceled = true' here!
2336 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2337 }
mpagenko38662d02021-08-11 09:45:19 +00002338 }
mpagenko80622a52021-02-09 16:53:23 +00002339
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002341 return nil
2342}
2343
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2345 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 +05302346
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002347 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002349 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002351 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002352 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002353 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002354
mpagenkoa40e99a2020-11-17 13:50:39 +00002355 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2356 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2357 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2358 * disable/enable toggling here to allow traffic
2359 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2360 * like the py comment says:
2361 * # start by locking all the unis till mib sync and initial mib is downloaded
2362 * # this way we can capture the port down/up events when we are ready
2363 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302364
mpagenkoa40e99a2020-11-17 13:50:39 +00002365 // Init Uni Ports to Admin locked state
2366 // *** should generate UniLockStateDone event *****
2367 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002369 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002371 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002372 }
2373}
2374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2376 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 /* Mib download procedure -
2378 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2379 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002380 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002381 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002382 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002383 return
2384 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302386 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002387 if pMibDlFsm.Is(mib.DlStDisabled) {
2388 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2389 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 +05302390 // maybe try a FSM reset and then again ... - TODO!!!
2391 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002392 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002394 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2395 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302396 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002397 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302398 //Begin MIB data download (running autonomously)
2399 }
2400 }
2401 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302404 // maybe try a FSM reset and then again ... - TODO!!!
2405 }
2406 /***** Mib download started */
2407 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 }
2410}
2411
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302413 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002414 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2415 if pDevEntry == nil {
2416 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2417 return
2418 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002420 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002421 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002422 // update device info in core
2423 pDevEntry.MutexPersOnuConfig.RLock()
2424 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2425 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2426 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2427 pDevEntry.MutexPersOnuConfig.RUnlock()
2428 dh.logicalDeviceID = dh.DeviceID
2429 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2430 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2431 }
2432 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002433 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2434 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2435 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2436 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002437 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002439 ConnStatus: voltha.ConnectStatus_REACHABLE,
2440 OperStatus: voltha.OperStatus_ACTIVE,
2441 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302442 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302444 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002445 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302446 }
2447 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302448 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302450 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002451 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002454 var waitForOmciProcessor sync.WaitGroup
2455 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002456 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002457 go dh.StartCollector(ctx, &waitForOmciProcessor)
2458 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002459 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 if !dh.GetAlarmManagerIsRunning(ctx) {
2461 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002462 }
2463
Girish Gowdrae95687a2021-09-08 16:30:58 -07002464 // Start flow handler routines per UNI
2465 for _, uniPort := range dh.uniEntityMap {
2466 // only if this port was enabled for use by the operator at startup
2467 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2468 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2469 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2470 }
2471 }
2472 }
2473
Girish Gowdrae0140f02021-02-02 16:55:09 -08002474 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002476 // There is no way we should be landing here, but if we do then
2477 // there is nothing much we can do about this other than log error
2478 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2479 }
2480
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002482
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 pDevEntry.MutexPersOnuConfig.RLock()
2484 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2485 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302486 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002488 dh.mutexForDisableDeviceRequested.Lock()
2489 dh.disableDeviceRequested = true
2490 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002491 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002492 // reconcilement will be continued after ani config is done
2493 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002495 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002496 dh.mutexForDisableDeviceRequested.RLock()
2497 if !dh.disableDeviceRequested {
2498 if dh.pUnlockStateFsm == nil {
2499 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2500 } else { //UnlockStateFSM already init
2501 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2502 dh.runUniLockFsm(ctx, false)
2503 }
2504 dh.mutexForDisableDeviceRequested.RUnlock()
2505 } else {
2506 dh.mutexForDisableDeviceRequested.RUnlock()
2507 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002508 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302509 }
2510}
2511
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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002542 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002544
mpagenko44bd8362021-11-15 11:40:05 +00002545 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002546 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002548 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002549 OperStatus: voltha.OperStatus_UNKNOWN,
2550 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002551 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002553 }
2554
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002556 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002557 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002558
2559 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002560 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002561
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002563 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002565 return
2566 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002567 pDevEntry.MutexPersOnuConfig.Lock()
2568 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2569 pDevEntry.MutexPersOnuConfig.Unlock()
2570 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002573 }
mpagenko900ee4b2020-10-12 11:56:34 +00002574}
2575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002576func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002577 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002579 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002581 ConnStatus: voltha.ConnectStatus_REACHABLE,
2582 OperStatus: voltha.OperStatus_ACTIVE,
2583 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002584 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002586 }
2587
dbainbri4d3a0dc2020-12-02 00:33:42 +00002588 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002590 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002591 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002592
2593 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002594 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002595
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002597 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002598 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002599 return
2600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 pDevEntry.MutexPersOnuConfig.Lock()
2602 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2603 pDevEntry.MutexPersOnuConfig.Unlock()
2604 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002607 }
mpagenko900ee4b2020-10-12 11:56:34 +00002608}
2609
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002610func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2611 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2612 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002613 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002614 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002615 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002616 OperStatus: voltha.OperStatus_FAILED,
2617 }); err != nil {
2618 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2619 }
2620}
2621
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2623 if devEvent == cmn.OmciAniConfigDone {
2624 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002625 // attention: the device reason update is done based on ONU-UNI-Port related activity
2626 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002627 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002628 // 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 +00002629 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302630 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002632 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2633 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2634 dh.mutexReconcilingFirstPassFlag.Lock()
2635 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302636 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002637 dh.reconcilingFirstPass = false
2638 go dh.ReconcileDeviceFlowConfig(ctx)
2639 }
2640 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002641 }
2642 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002644 // attention: the device reason update is done based on ONU-UNI-Port related activity
2645 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002647 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2648 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002649 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002650 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302651}
2652
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002653func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002655 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302656 // attention: the device reason update is done based on ONU-UNI-Port related activity
2657 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302658
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2660 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002661 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002662 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002663 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002664 }
2665 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002667 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002668 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002669 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302670 }
mpagenkof1fc3862021-02-16 10:09:52 +00002671
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002672 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002673 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002674 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002675 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002676 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002677 }
2678 } else {
2679 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002681 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302682}
2683
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302684// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302686 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002688 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002689 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002690 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002692 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002693 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002694 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002696 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002697 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002698 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002699 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002700 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002701 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002702 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002704 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002705 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002706 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002707 case cmn.UniEnableStateFailed:
2708 {
2709 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2710 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002711 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002712 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002714 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002716 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002717 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002718 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002720 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002722 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002723 default:
2724 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002726 }
2727 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002728}
2729
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002730func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002731 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002732 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302733 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002734 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002735 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002736 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302737 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002739 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002740 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 +00002741 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002742 //store UniPort with the System-PortNumber key
2743 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002745 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002747 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002748 } //error logging already within UniPort method
2749 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302750 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002751 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002752 }
2753 }
2754}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002755
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002756func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2757 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002758 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002760 return
2761 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002762 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002764 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2765 for _, mgmtEntityID := range pptpInstKeys {
2766 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002768 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2769 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002770 }
2771 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002772 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002773 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002775 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2776 for _, mgmtEntityID := range veipInstKeys {
2777 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002778 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002779 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2780 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002781 }
2782 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002783 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002784 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002785 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002786 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2787 for _, mgmtEntityID := range potsInstKeys {
2788 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002790 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2791 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002792 }
2793 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002795 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002796 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002798 return
2799 }
2800
mpagenko2c3f6c52021-11-23 11:22:10 +00002801 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2802 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2803 // 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 -07002804 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2805 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2806 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002807 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2808 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002809 for i := 0; i < int(uniCnt); i++ {
2810 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002811 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002812 }
2813}
2814
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2816func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002817 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302818 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002819 // with following remark:
2820 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2821 // # load on the core
2822
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002823 // 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 +00002824
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002825 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002826 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002827 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2828 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2829 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2830 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002831 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002833 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002835 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002836 PortNo: port.PortNo,
2837 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002838 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 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 -04002840 }
2841 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002842 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302843 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002844 }
mpagenko3af1f032020-06-10 08:53:41 +00002845 }
2846 }
2847}
2848
2849// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002850func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2851 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002852 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2853 for uniNo, uniPort := range dh.uniEntityMap {
2854 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002855
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2857 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2858 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2859 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002860 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002862 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002863 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002864 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 PortNo: port.PortNo,
2866 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002867 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 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 -04002869 }
2870 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002871 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302872 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002873 }
2874
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002875 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002876 }
2877}
2878
2879// ONU_Active/Inactive announcement on system KAFKA bus
2880// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002882 var de voltha.DeviceEvent
2883 eventContext := make(map[string]string)
2884 //Populating event context
2885 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002886 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002887 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002889 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002890 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 +00002891 }
2892 oltSerialNumber := parentDevice.SerialNumber
2893
2894 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2895 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2896 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302897 eventContext["olt-serial-number"] = oltSerialNumber
2898 eventContext["device-id"] = aDeviceID
2899 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002900 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002901 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2902 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002903 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2904 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2906 deviceEntry.MutexPersOnuConfig.RUnlock()
2907 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002909 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2910 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2911 } else {
2912 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2913 log.Fields{"device-id": aDeviceID})
2914 return
2915 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002916
2917 /* Populating device event body */
2918 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302919 de.ResourceId = aDeviceID
2920 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002921 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2922 de.Description = fmt.Sprintf("%s Event - %s - %s",
2923 cEventObjectType, cOnuActivatedEvent, "Raised")
2924 } else {
2925 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2926 de.Description = fmt.Sprintf("%s Event - %s - %s",
2927 cEventObjectType, cOnuActivatedEvent, "Cleared")
2928 }
2929 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302930 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302932 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002933 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302934 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302935 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002936}
2937
Himani Chawla4d908332020-08-31 12:30:20 +05302938// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2940 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002941 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302942 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002944 sFsmName = "LockStateFSM"
2945 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002947 sFsmName = "UnLockStateFSM"
2948 }
mpagenko3af1f032020-06-10 08:53:41 +00002949
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002951 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002953 return
2954 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002956 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302957 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002958 dh.pLockStateFsm = pLSFsm
2959 } else {
2960 dh.pUnlockStateFsm = pLSFsm
2961 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002963 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002965 }
2966}
2967
2968// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002969func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002970 /* Uni Port lock/unlock procedure -
2971 ***** should run via 'adminDone' state and generate the argument requested event *****
2972 */
2973 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302974 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002976 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2977 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2979 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002980 }
2981 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002982 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002983 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2984 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2986 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002987 }
2988 }
2989 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2991 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002992 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002993 // maybe try a FSM reset and then again ... - TODO!!!
2994 } else {
2995 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002997 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002998 }
2999 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003000 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003002 // maybe try a FSM reset and then again ... - TODO!!!
3003 }
3004 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00003006 // maybe try a FSM reset and then again ... - TODO!!!
3007 }
3008}
3009
mpagenko80622a52021-02-09 16:53:23 +00003010// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003011// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003012func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00003014 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003016 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003018 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00003019 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003020 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003021 sFsmName, chUpgradeFsm)
3022 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003023 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003024 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3026 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003027 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003028 // maybe try a FSM reset and then again ... - TODO!!!
3029 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
3030 }
mpagenko59862f02021-10-11 08:53:18 +00003031 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003032 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3033 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003034 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3035 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003036 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003038 } else {
3039 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003040 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003041 // maybe try a FSM reset and then again ... - TODO!!!
3042 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
3043 }
3044 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003045 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003046 // maybe try a FSM reset and then again ... - TODO!!!
3047 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
3048 }
3049 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003051 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3052 }
3053 return nil
3054}
3055
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3057func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003058 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003059 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003060 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003061 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3062 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003063 dh.pLastUpgradeImageState = apImageState
3064 dh.lockUpgradeFsm.Unlock()
3065 //signal upgradeFsm removed using non-blocking channel send
3066 select {
3067 case dh.upgradeFsmChan <- struct{}{}:
3068 default:
3069 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003070 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003071 }
mpagenko80622a52021-02-09 16:53:23 +00003072}
3073
mpagenko15ff4a52021-03-02 10:09:20 +00003074// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3075func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003076 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003077 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003078 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003079 return
3080 }
3081
3082 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003083 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003084 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003085 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3086 dh.lockUpgradeFsm.RUnlock()
3087 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3088 return
3089 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003090 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003091 if pUpgradeStatemachine != nil {
3092 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3093 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 UpgradeState := pUpgradeStatemachine.Current()
3095 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3096 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3097 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003098 // 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 +00003099 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003100 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3101 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003102 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003103 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003105 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3106 dh.upgradeCanceled = true
3107 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3108 }
mpagenko15ff4a52021-03-02 10:09:20 +00003109 return
3110 }
mpagenko59862f02021-10-11 08:53:18 +00003111 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003112 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3113 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003114 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003115 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003116 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3117 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003118 return
3119 }
3120 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003122 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003123 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3124 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003125 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3126 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003127 return
3128 }
3129 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003130 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003131 }
3132 } else {
3133 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 +00003134 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003135 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3136 dh.upgradeCanceled = true
3137 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3138 }
mpagenko1f8e8822021-06-25 14:10:21 +00003139 }
mpagenko15ff4a52021-03-02 10:09:20 +00003140 return
3141 }
mpagenko59862f02021-10-11 08:53:18 +00003142 dh.lockUpgradeFsm.RUnlock()
3143 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3144 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003145 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3146 dh.upgradeCanceled = true
3147 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3148 }
mpagenko59862f02021-10-11 08:53:18 +00003149 return
3150 }
3151 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3152 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3153 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3154 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3155 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3156 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3157 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003158 }
mpagenko15ff4a52021-03-02 10:09:20 +00003159 }
3160 }
3161 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003163 }
mpagenko59862f02021-10-11 08:53:18 +00003164 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003165}
3166
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303167// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003169
3170 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003172 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003173 kvbackend := &db.Backend{
3174 Client: dh.pOpenOnuAc.kvClient,
3175 StoreType: dh.pOpenOnuAc.KVStoreType,
3176 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003177 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003178 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3179 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003180
mpagenkoaf801632020-07-03 10:00:42 +00003181 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003182}
khenaidoo7d3c5582021-08-11 18:09:44 -04003183func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303184 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003185
mpagenkodff5dda2020-08-28 11:52:01 +00003186 for _, field := range flow.GetOfbFields(apFlowItem) {
3187 switch field.Type {
3188 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3189 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003191 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3192 }
mpagenko01e726e2020-10-23 09:45:29 +00003193 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003194 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3195 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303196 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303198 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3199 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003200 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3201 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003202 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003203 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303204 return
mpagenkodff5dda2020-08-28 11:52:01 +00003205 }
3206 }
mpagenko01e726e2020-10-23 09:45:29 +00003207 */
mpagenkodff5dda2020-08-28 11:52:01 +00003208 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3209 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303210 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003211 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303212 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003213 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303214 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003216 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303217 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003218 }
3219 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3220 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303221 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303223 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003224 }
3225 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3226 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003227 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003228 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3229 }
3230 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3231 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003233 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3234 }
3235 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3236 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003238 "IPv4-DST": field.GetIpv4Dst()})
3239 }
3240 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3241 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003243 "IPv4-SRC": field.GetIpv4Src()})
3244 }
3245 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3246 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003248 "Metadata": field.GetTableMetadata()})
3249 }
3250 /*
3251 default:
3252 {
3253 //all other entires ignored
3254 }
3255 */
3256 }
3257 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303258}
mpagenkodff5dda2020-08-28 11:52:01 +00003259
khenaidoo7d3c5582021-08-11 18:09:44 -04003260func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003261 for _, action := range flow.GetActions(apFlowItem) {
3262 switch action.Type {
3263 /* not used:
3264 case of.OfpActionType_OFPAT_OUTPUT:
3265 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003266 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003267 "Output": action.GetOutput()})
3268 }
3269 */
3270 case of.OfpActionType_OFPAT_PUSH_VLAN:
3271 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003272 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003273 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3274 }
3275 case of.OfpActionType_OFPAT_SET_FIELD:
3276 {
3277 pActionSetField := action.GetSetField()
3278 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003280 "OxcmClass": pActionSetField.Field.OxmClass})
3281 }
3282 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303283 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303285 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003286 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303287 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003288 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303289 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003290 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003291 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003292 "Type": pActionSetField.Field.GetOfbField().Type})
3293 }
3294 }
3295 /*
3296 default:
3297 {
3298 //all other entires ignored
3299 }
3300 */
3301 }
3302 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303303}
3304
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303305// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003306func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003307 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303308 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3309 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303310 var loSetPcp uint8
3311 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303312 var loIPProto uint32
3313 /* the TechProfileId is part of the flow Metadata - compare also comment within
3314 * OLT-Adapter:openolt_flowmgr.go
3315 * Metadata 8 bytes:
3316 * Most Significant 2 Bytes = Inner VLAN
3317 * Next 2 Bytes = Tech Profile ID(TPID)
3318 * Least Significant 4 Bytes = Port ID
3319 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3320 * subscriber related flows.
3321 */
3322
dbainbri4d3a0dc2020-12-02 00:33:42 +00003323 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303324 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003325 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003326 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003327 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303328 }
mpagenko551a4d42020-12-08 18:09:20 +00003329 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003330 loCookie := apFlowItem.GetCookie()
3331 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303332 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303334 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303335
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303336 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003337 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303338 if loIPProto == 2 {
3339 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3340 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003341 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003342 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303343 return nil
3344 }
mpagenko01e726e2020-10-23 09:45:29 +00003345 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003346 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003347
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303348 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3349 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003350 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003351 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003352 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3353 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3354 //TODO!!: Use DeviceId within the error response to rwCore
3355 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003356 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003357 }
3358 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003359 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003360 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303361 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3362 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3363 loSetVlan = loMatchVlan
3364 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 +00003365 } else {
3366 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3367 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3368 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303369 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003370 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003371 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003372 }
mpagenko9a304ea2020-12-16 15:54:01 +00003373
khenaidoo42dcdfd2021-10-19 17:34:12 -04003374 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003375 if apFlowMetaData != nil {
3376 meter = apFlowMetaData.Meters[0]
3377 }
mpagenkobc4170a2021-08-17 16:42:10 +00003378 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3379 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3380 // when different rules are requested concurrently for the same uni
3381 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3382 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3383 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003384 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3385 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003386 //SetUniFlowParams() may block on some rule that is suspended-to-add
3387 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003388 // Also the error is returned to caller via response channel
3389 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303390 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003391 dh.lockVlanConfig.RUnlock()
3392 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003393 return
mpagenkodff5dda2020-08-28 11:52:01 +00003394 }
mpagenkobc4170a2021-08-17 16:42:10 +00003395 dh.lockVlanConfig.RUnlock()
3396 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003397 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303398 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003399 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003400 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003401 if err != nil {
3402 *respChan <- err
3403 }
mpagenko01e726e2020-10-23 09:45:29 +00003404}
3405
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303406// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003407func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003408 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3409 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3410 //no extra check is done on the rule parameters
3411 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3412 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3413 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3414 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003415 // - 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 +00003416 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003417 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003418
3419 /* TT related temporary workaround - should not be needed anymore
3420 for _, field := range flow.GetOfbFields(apFlowItem) {
3421 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3422 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003423 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003424 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3425 if loIPProto == 2 {
3426 // 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 +00003427 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003428 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003429 return nil
3430 }
3431 }
3432 } //for all OfbFields
3433 */
3434
mpagenko9a304ea2020-12-16 15:54:01 +00003435 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003436 dh.lockVlanConfig.RLock()
3437 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3439 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003440 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3441 return
mpagenko01e726e2020-10-23 09:45:29 +00003442 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003443 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003445 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003446 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003447 // Push response on the response channel
3448 if respChan != nil {
3449 // 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
3450 select {
3451 case *respChan <- nil:
3452 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3453 default:
3454 }
3455 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003457}
3458
Himani Chawla26e555c2020-08-31 12:30:20 +05303459// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003460// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003461// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003462func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303463 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003464 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003465
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003467 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003468 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3469 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003470 }
3471
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003472 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3473 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303474 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003475 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003476 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3477 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003478 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3479 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003480 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003481 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3482 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003483 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3484 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003485 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003486 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303487 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003488 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3490 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003491 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003492 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3494 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003495 }
3496 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003497 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003498 "device-id": dh.DeviceID})
3499 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003500 }
3501 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003502 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003503 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3504 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003505 }
3506 return nil
3507}
3508
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303509// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003510// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003511func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003512 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003514 for _, uniPort := range dh.uniEntityMap {
3515 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003517 pCurrentUniPort = uniPort
3518 break //found - end search loop
3519 }
3520 }
3521 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003522 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003524 return
3525 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003526 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003527}
3528
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303529// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003530func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003531 //TODO!! verify and start pending flow configuration
3532 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3533 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303534 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003535 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003537 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003538 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003540 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003541 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003542 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003543 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3544 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003545 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003547 } else {
3548 /***** UniVlanConfigFsm continued */
3549 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3551 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003552 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003553 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3554 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003555 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003556 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003557 } else {
3558 /***** UniVlanConfigFsm continued */
3559 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003560 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3561 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003562 }
mpagenkodff5dda2020-08-28 11:52:01 +00003563 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003564 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3566 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003567 }
3568 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003569 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 +00003570 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3571 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003572 }
3573 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003574 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003575 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003576 }
mpagenkof1fc3862021-02-16 10:09:52 +00003577 } else {
3578 dh.lockVlanConfig.RUnlock()
3579 }
mpagenkodff5dda2020-08-28 11:52:01 +00003580}
3581
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303582// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003583// 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 +00003584func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003585 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003586 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003587 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003588 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003589 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003590 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003591}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003592
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303593// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003595 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3596 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3597 // obviously then parallel processing on the cancel must be avoided
3598 // deadline context to ensure completion of background routines waited for
3599 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3600 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3601 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003603 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003604 var wg sync.WaitGroup
3605 wg.Add(1) // for the 1 go routine to finish
3606
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003608 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3609
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003610 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003611}
3612
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303613// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3614// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003615func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3616 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003617
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303619 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003620 return nil
3621 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003622 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003624 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003625 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3627 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003628 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003629 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003630
mpagenkof1fc3862021-02-16 10:09:52 +00003631 if aWriteToKvStore {
3632 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3633 }
3634 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003635}
3636
dbainbri4d3a0dc2020-12-02 00:33:42 +00003637func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003638 defer cancel() //ensure termination of context (may be pro forma)
3639 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003640 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003642}
3643
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303644// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3645//
3646// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003647func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3648 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3649 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3650 dh.mutexDeviceReason.Lock()
3651 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003652 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003653 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003654 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003655 DeviceId: dh.DeviceID,
3656 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003657 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003658 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003659 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003660 return err
3661 }
mpagenkoe4782082021-11-25 12:04:26 +00003662 } else {
3663 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 +00003664 }
mpagenkoe4782082021-11-25 12:04:26 +00003665 dh.deviceReason = deviceReason
3666 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3667 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003668 return nil
3669}
3670
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003671func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3672 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003673 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003674 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3675 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003676 }
mpagenkof1fc3862021-02-16 10:09:52 +00003677 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003678}
3679
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003680// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003681// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003682func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3683 dh.lockDevice.RLock()
3684 defer dh.lockDevice.RUnlock()
3685 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003687 }
3688 return 0, errors.New("error-fetching-uni-port")
3689}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003690
3691// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003692func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3693 var errorsList []error
3694 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 -08003695
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003696 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3697 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3698 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3699
3700 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3701 // successfully.
3702 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3703 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3704 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705 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 -08003706 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003707 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003708 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003709 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003710}
3711
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003712func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3713 var err error
3714 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003715 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003716
3717 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003719 errorsList = append(errorsList, err)
3720 }
3721 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003722 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003723
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003724 return errorsList
3725}
3726
3727func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3728 var err error
3729 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003730 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003731 // Check if group metric related config is updated
3732 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003733 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3734 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3735 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003736
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003737 if ok && m.Frequency != v.GroupFreq {
3738 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003739 errorsList = append(errorsList, err)
3740 }
3741 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003742 if ok && m.Enabled != v.Enabled {
3743 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003744 errorsList = append(errorsList, err)
3745 }
3746 }
3747 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003748 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003749 return errorsList
3750}
3751
3752func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3753 var err error
3754 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003755 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003756 // Check if standalone metric related config is updated
3757 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3759 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3760 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003761
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003762 if ok && m.Frequency != v.SampleFreq {
3763 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003764 errorsList = append(errorsList, err)
3765 }
3766 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767 if ok && m.Enabled != v.Enabled {
3768 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003769 errorsList = append(errorsList, err)
3770 }
3771 }
3772 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003773 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003774 return errorsList
3775}
3776
3777// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003778func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003779 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003780
3781 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003782 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303783 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003784 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003785 // Initialize the next metric collection time.
3786 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3787 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003788 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003789 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303790 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3791 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003792 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303793
Girish Gowdrae09a6202021-01-12 18:10:59 -08003794 select {
3795 case <-dh.stopCollector:
3796 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003797 // Stop the L2 PM FSM
3798 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003799 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3800 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3801 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003802 }
3803 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003805 }
3806 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003807 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3808 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003809 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003810 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3811 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003812 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003813
Girish Gowdrae09a6202021-01-12 18:10:59 -08003814 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303815 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003816 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3817 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3818 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3819 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003820 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003821 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
3822 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003823 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003824 } else {
3825 if dh.pmConfigs.Grouped { // metrics are managed as a group
3826 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003828
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3830 // 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 -08003831 // 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 +00003832 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3833 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003834 }
3835 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003836 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3837 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3838 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3839 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003840 }
3841 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003842 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003843
3844 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3846 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3847 // 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 -08003848 // 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 +00003849 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003850 prevInternal := g.NextCollectionInterval
3851 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003852 }
3853 }
3854 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003855 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3856 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3857 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003858 prevInternal := m.NextCollectionInterval
3859 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003860 }
3861 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003862 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003863 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003864 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003865 } */
3866 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003867 }
3868 }
3869}
kesavandfdf77632021-01-26 23:40:33 -05003870
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003871func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003872
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003873 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3874 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003875}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003876
Himani Chawla43f95ff2021-06-03 00:24:12 +05303877func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3878 if dh.pOnuMetricsMgr == nil {
3879 return &extension.SingleGetValueResponse{
3880 Response: &extension.GetValueResponse{
3881 Status: extension.GetValueResponse_ERROR,
3882 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3883 },
3884 }
3885 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303886 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303887 return resp
3888}
3889
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003890func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3891
3892 var err error
3893 var pDevOmciCC *cmn.OmciCC
3894 if dh.pOnuOmciDevice == nil {
3895 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3896 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3897 } else {
3898 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3899 if pDevOmciCC == nil {
3900 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3901 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3902 }
3903 }
3904 if err != nil {
3905 return &extension.SingleGetValueResponse{
3906 Response: &extension.GetValueResponse{
3907 Status: extension.GetValueResponse_ERROR,
3908 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3909 },
3910 },
3911 err
3912 }
3913 return pDevOmciCC.GetOmciCounters(), nil
3914}
3915
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003916func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3917 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003918 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003919 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003920 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003921}
3922
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003923func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003924 var pAdapterFsm *cmn.AdapterFsm
3925 //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 +00003926 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003927 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003928 {
mpagenkofbf577d2021-10-12 11:44:33 +00003929 if dh.pOnuOmciDevice != nil {
3930 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3931 } else {
3932 return true //FSM not active - so there is no activity on omci
3933 }
mpagenkof1fc3862021-02-16 10:09:52 +00003934 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003935 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003936 {
mpagenkofbf577d2021-10-12 11:44:33 +00003937 if dh.pOnuOmciDevice != nil {
3938 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3939 } else {
3940 return true //FSM not active - so there is no activity on omci
3941 }
mpagenkof1fc3862021-02-16 10:09:52 +00003942 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003944 {
mpagenkofbf577d2021-10-12 11:44:33 +00003945 if dh.pLockStateFsm != nil {
3946 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3947 } else {
3948 return true //FSM not active - so there is no activity on omci
3949 }
mpagenkof1fc3862021-02-16 10:09:52 +00003950 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003951 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003952 {
mpagenkofbf577d2021-10-12 11:44:33 +00003953 if dh.pUnlockStateFsm != nil {
3954 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3955 } else {
3956 return true //FSM not active - so there is no activity on omci
3957 }
mpagenkof1fc3862021-02-16 10:09:52 +00003958 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003959 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003960 {
mpagenkofbf577d2021-10-12 11:44:33 +00003961 if dh.pOnuMetricsMgr != nil {
3962 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003963 } else {
3964 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003965 }
3966 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003967 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003968 {
3969 dh.lockUpgradeFsm.RLock()
3970 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003971 if dh.pOnuUpradeFsm != nil {
3972 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3973 } else {
3974 return true //FSM not active - so there is no activity on omci
3975 }
mpagenko80622a52021-02-09 16:53:23 +00003976 }
mpagenkof1fc3862021-02-16 10:09:52 +00003977 default:
3978 {
3979 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003981 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003982 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003983 }
mpagenkofbf577d2021-10-12 11:44:33 +00003984 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3985 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3986 }
3987 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003988}
3989
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003990func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3991 for _, v := range dh.pOnuTP.PAniConfigFsm {
3992 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003993 return false
3994 }
3995 }
3996 return true
3997}
3998
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003999func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004000 dh.lockVlanConfig.RLock()
4001 defer dh.lockVlanConfig.RUnlock()
4002 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004003 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004004 return false
4005 }
4006 }
4007 return true //FSM not active - so there is no activity on omci
4008}
4009
4010func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4011 dh.lockVlanConfig.RLock()
4012 defer dh.lockVlanConfig.RUnlock()
4013 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004014 if v.PAdaptFsm.PFsm != nil {
4015 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004016 return true //there is at least one VLAN FSM with some active configuration
4017 }
4018 }
4019 }
4020 return false //there is no VLAN FSM with some active configuration
4021}
4022
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004024 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4025 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4026 return false
4027 }
4028 }
4029 // a further check is done to identify, if at least some data traffic related configuration exists
4030 // 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])
4031 return dh.checkUserServiceExists(ctx)
4032}
4033
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004034func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304035 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 +00004036 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004038 // TODO: fatal error reset ONU, delete deviceHandler!
4039 return
4040 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004041 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4042 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004043}
4044
4045func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4046 dh.mutexCollectorFlag.Lock()
4047 dh.collectorIsRunning = flagValue
4048 dh.mutexCollectorFlag.Unlock()
4049}
4050
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004051func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004052 dh.mutexCollectorFlag.RLock()
4053 flagValue := dh.collectorIsRunning
4054 dh.mutexCollectorFlag.RUnlock()
4055 return flagValue
4056}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304057
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304058func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4059 dh.mutextAlarmManagerFlag.Lock()
4060 dh.alarmManagerIsRunning = flagValue
4061 dh.mutextAlarmManagerFlag.Unlock()
4062}
4063
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004064func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304065 dh.mutextAlarmManagerFlag.RLock()
4066 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004067 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304068 dh.mutextAlarmManagerFlag.RUnlock()
4069 return flagValue
4070}
4071
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004072func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004073 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304074
4075 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004076 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304077 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304078 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304079 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304080 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004081 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4082 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304083 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304084 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004085 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4086 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304087 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304088 }
4089}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004090
Girish Gowdrae95687a2021-09-08 16:30:58 -07004091func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4092 dh.mutexFlowMonitoringRoutineFlag.Lock()
4093 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004094 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004095 dh.isFlowMonitoringRoutineActive[uniID] = flag
4096}
4097
4098func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4099 dh.mutexFlowMonitoringRoutineFlag.RLock()
4100 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4101 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004102 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004103 return dh.isFlowMonitoringRoutineActive[uniID]
4104}
4105
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004106func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304107 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004108
Maninder7961d722021-06-16 22:10:28 +05304109 connectStatus := voltha.ConnectStatus_UNREACHABLE
4110 operState := voltha.OperStatus_UNKNOWN
4111
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004113 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004114 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004115 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004116 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004117 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304118 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004119 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4120 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4121 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4122 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4123 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4124 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4125 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4126 // However, a later refactoring of the functionality remains unaffected.
4127 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004128 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004129 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304130 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004131 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304132 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004133 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004134 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304135 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004136 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4137 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304138 operState = voltha.OperStatus_ACTIVE
4139 } else {
4140 operState = voltha.OperStatus_ACTIVATING
4141 }
4142 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004143 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4144 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4145 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304146 operState = voltha.OperStatus_DISCOVERED
4147 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004148 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004149 logger.Debugw(ctx, "Core DeviceStateUpdate",
4150 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304151 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304152 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004153 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004154 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004155 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004156 ConnStatus: connectStatus,
4157 OperStatus: operState,
4158 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304159 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004160 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304161 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004162 } else {
Maninderb5187552021-03-23 22:23:42 +05304163 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004164 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304165
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004166 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304167 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004168 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004169 } else {
4170 onuDevEntry.MutexPersOnuConfig.RLock()
4171 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4172 connectStatus = voltha.ConnectStatus_REACHABLE
4173 }
4174 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304175 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004176 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004177 }
mpagenko101ac942021-11-16 15:01:29 +00004178 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004179 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004181 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304182
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004183 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304184 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004185 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004186 } else {
4187 onuDevEntry.MutexPersOnuConfig.RLock()
4188 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4189 connectStatus = voltha.ConnectStatus_REACHABLE
4190 }
4191 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304192 }
4193
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004194 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304195
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004196 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004197 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004198 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004199 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004200 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004201
4202 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4203 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4204 } else {
4205 onuDevEntry.MutexReconciledTpInstances.Lock()
4206 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4207 onuDevEntry.MutexReconciledTpInstances.Unlock()
4208 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004209 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004210 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004211 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304212 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004213 dh.reconciling = cSkipOnuConfigReconciling
4214 } else {
4215 dh.reconciling = cOnuConfigReconciling
4216 }
4217 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004218}
4219
mpagenko101ac942021-11-16 15:01:29 +00004220func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304221 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004222 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004223 dh.sendChReconcileFinished(success)
4224 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4225 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4226 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004227 } else {
mpagenko101ac942021-11-16 15:01:29 +00004228 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004229 }
4230}
4231
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004232func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004233 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004234 defer dh.mutexReconcilingFlag.RUnlock()
4235 return dh.reconciling != cNoReconciling
4236}
4237
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004238func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004239 dh.mutexReconcilingFlag.RLock()
4240 defer dh.mutexReconcilingFlag.RUnlock()
4241 return dh.reconciling == cSkipOnuConfigReconciling
4242}
4243
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004244func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4245 dh.mutexReconcilingFirstPassFlag.Lock()
4246 dh.reconcilingFirstPass = value
4247 dh.mutexReconcilingFirstPassFlag.Unlock()
4248}
4249
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004250func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4251 dh.mutexReconcilingReasonUpdate.Lock()
4252 dh.reconcilingReasonUpdate = value
4253 dh.mutexReconcilingReasonUpdate.Unlock()
4254}
4255
4256func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4257 dh.mutexReconcilingReasonUpdate.RLock()
4258 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4259 return dh.reconcilingReasonUpdate
4260}
4261
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004262func (dh *deviceHandler) getDeviceReason() uint8 {
4263 dh.mutexDeviceReason.RLock()
4264 value := dh.deviceReason
4265 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004266 return value
4267}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004268
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004269func (dh *deviceHandler) GetDeviceReasonString() string {
4270 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004271}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004272
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004273func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004274 dh.mutexReadyForOmciConfig.Lock()
4275 dh.readyForOmciConfig = flagValue
4276 dh.mutexReadyForOmciConfig.Unlock()
4277}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004278func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004279 dh.mutexReadyForOmciConfig.RLock()
4280 flagValue := dh.readyForOmciConfig
4281 dh.mutexReadyForOmciConfig.RUnlock()
4282 return flagValue
4283}
Maninder7961d722021-06-16 22:10:28 +05304284
4285func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004286 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304287 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004288 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304289 }
4290
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004291 logger.Debugw(ctx, "Core DeviceStateUpdate",
4292 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004293 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004294 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004295 ConnStatus: connectStatus,
4296 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4297 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304298 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004299 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304300 }
4301}
khenaidoo7d3c5582021-08-11 18:09:44 -04004302
4303/*
4304Helper functions to communicate with Core
4305*/
4306
4307func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4308 cClient, err := dh.coreClient.GetCoreServiceClient()
4309 if err != nil || cClient == nil {
4310 return nil, err
4311 }
4312 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4313 defer cancel()
4314 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4315 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4316}
4317
khenaidoo42dcdfd2021-10-19 17:34:12 -04004318func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004319 cClient, err := dh.coreClient.GetCoreServiceClient()
4320 if err != nil || cClient == nil {
4321 return err
4322 }
4323 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4324 defer cancel()
4325 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004326 logger.Debugw(subCtx, "device-updated-in-core",
4327 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004328 return err
4329}
4330
4331func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4332 cClient, err := dh.coreClient.GetCoreServiceClient()
4333 if err != nil || cClient == nil {
4334 return err
4335 }
4336 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4337 defer cancel()
4338 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004339 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4340 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004341 return err
4342}
4343
4344func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4345 cClient, err := dh.coreClient.GetCoreServiceClient()
4346 if err != nil || cClient == nil {
4347 return err
4348 }
4349 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4350 defer cancel()
4351 _, err = cClient.DeviceUpdate(subCtx, device)
4352 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4353 return err
4354}
4355
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004356func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004357 cClient, err := dh.coreClient.GetCoreServiceClient()
4358 if err != nil || cClient == nil {
4359 return err
4360 }
4361 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4362 defer cancel()
4363 _, err = cClient.PortCreated(subCtx, port)
4364 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4365 return err
4366}
4367
khenaidoo42dcdfd2021-10-19 17:34:12 -04004368func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004369 cClient, err := dh.coreClient.GetCoreServiceClient()
4370 if err != nil || cClient == nil {
4371 return err
4372 }
4373 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4374 defer cancel()
4375 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004376 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 -04004377 return err
4378}
4379
khenaidoo42dcdfd2021-10-19 17:34:12 -04004380func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004381 cClient, err := dh.coreClient.GetCoreServiceClient()
4382 if err != nil || cClient == nil {
4383 return err
4384 }
4385 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4386 defer cancel()
4387 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004388 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 -04004389 return err
4390}
4391
4392/*
4393Helper functions to communicate with parent adapter
4394*/
4395
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004396func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4397 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4398
4399 var request = ia.TechProfileInstanceRequestMessage{
4400 DeviceId: dh.DeviceID,
4401 TpInstancePath: aTpPath,
4402 ParentDeviceId: dh.parentID,
4403 ParentPonPort: dh.device.ParentPortNo,
4404 OnuId: dh.device.ProxyAddress.OnuId,
4405 UniId: uint32(aUniID),
4406 }
4407
4408 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004409 if err != nil || pgClient == nil {
4410 return nil, err
4411 }
4412 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4413 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004414 logger.Debugw(subCtx, "get-tech-profile-instance",
4415 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004416 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004417}
4418
Girish Gowdrae95687a2021-09-08 16:30:58 -07004419// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4420// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4421func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4422 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4423 dh.setFlowMonitoringIsRunning(uniID, true)
4424 for {
4425 select {
4426 // block on the channel to receive an incoming flow
4427 // process the flow completely before proceeding to handle the next flow
4428 case flowCb := <-dh.flowCbChan[uniID]:
4429 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304430 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004431 respChan := make(chan error)
4432 if flowCb.addFlow {
4433 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4434 } else {
4435 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4436 }
4437 // Block on response and tunnel it back to the caller
4438 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304439 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004440 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4441 case <-dh.stopFlowMonitoringRoutine[uniID]:
4442 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4443 dh.setFlowMonitoringIsRunning(uniID, false)
4444 return
4445 }
4446 }
4447}
4448
kesavand011d5162021-11-25 19:21:06 +05304449func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4450 request.ParentDeviceId = dh.GetProxyAddressID()
4451 request.ChildDeviceId = dh.DeviceID
4452 request.ProxyAddress = dh.GetProxyAddress()
4453 request.ConnectStatus = common.ConnectStatus_REACHABLE
4454
4455 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4456 if err != nil || pgClient == nil {
4457 return err
4458 }
4459 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4460 defer cancel()
4461 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4462 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4463 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004464 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4465 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304466 }
4467 return err
4468}
4469
khenaidoo42dcdfd2021-10-19 17:34:12 -04004470func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004471 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4472 if err != nil || pgClient == nil {
4473 return err
4474 }
4475 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4476 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004477 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004478 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004479 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4480 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004481 if status.Code(err) == codes.Unavailable {
4482 dh.setOltAvailable(false)
4483 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004484 logger.Errorw(ctx, "omci-failure",
4485 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004486 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004487 }
4488 return err
4489}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004490
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004491func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4492 // Check if there are additional TCONT instances necessary/available
4493 pDevEntry.MutexPersOnuConfig.Lock()
4494 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4495 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4496 pDevEntry.MutexPersOnuConfig.Unlock()
4497 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4498 logger.Debugw(ctx, "checking available TCONT instances",
4499 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4500 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4501 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4502 log.Fields{"device-id": dh.device.Id})
4503 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4504 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4505 }
4506 } else {
4507 pDevEntry.MutexPersOnuConfig.Unlock()
4508 }
4509 // Check if there are enough PrioQueue instances available
4510 if dh.pOnuTP != nil {
4511 var numberOfUsPrioQueueDbInsts int
4512
4513 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4514 for _, mgmtEntityID := range queueInstKeys {
4515 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4516 numberOfUsPrioQueueDbInsts++
4517 }
4518 }
4519 // Check if there is an upstream PriorityQueue instance available for each Gem port
4520 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4521 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4522 log.Fields{"device-id": dh.DeviceID,
4523 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4524 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4525 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4526
4527 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4528 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4529 log.Fields{"device-id": dh.device.Id})
4530 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4531 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4532 }
4533 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4534 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4535 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4536 } else {
4537 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4538 log.Fields{"device-id": dh.DeviceID})
4539 }
4540 return nil
4541}
4542
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004543// GetDeviceID - TODO: add comment
4544func (dh *deviceHandler) GetDeviceID() string {
4545 return dh.DeviceID
4546}
4547
4548// GetProxyAddressID - TODO: add comment
4549func (dh *deviceHandler) GetProxyAddressID() string {
4550 return dh.device.ProxyAddress.GetDeviceId()
4551}
4552
4553// GetProxyAddressType - TODO: add comment
4554func (dh *deviceHandler) GetProxyAddressType() string {
4555 return dh.device.ProxyAddress.GetDeviceType()
4556}
4557
4558// GetProxyAddress - TODO: add comment
4559func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4560 return dh.device.ProxyAddress
4561}
4562
4563// GetEventProxy - TODO: add comment
4564func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4565 return dh.EventProxy
4566}
4567
4568// GetOmciTimeout - TODO: add comment
4569func (dh *deviceHandler) GetOmciTimeout() int {
4570 return dh.pOpenOnuAc.omciTimeout
4571}
4572
4573// GetAlarmAuditInterval - TODO: add comment
4574func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4575 return dh.pOpenOnuAc.alarmAuditInterval
4576}
4577
4578// GetDlToOnuTimeout4M - TODO: add comment
4579func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4580 return dh.pOpenOnuAc.dlToOnuTimeout4M
4581}
4582
4583// GetUniEntityMap - TODO: add comment
4584func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4585 return &dh.uniEntityMap
4586}
4587
4588// GetPonPortNumber - TODO: add comment
4589func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4590 return &dh.ponPortNumber
4591}
4592
4593// GetUniVlanConfigFsm - TODO: add comment
4594func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004595 dh.lockVlanConfig.RLock()
4596 value := dh.UniVlanConfigFsmMap[uniID]
4597 dh.lockVlanConfig.RUnlock()
4598 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004599}
4600
4601// GetOnuAlarmManager - TODO: add comment
4602func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4603 return dh.pAlarmMgr
4604}
4605
4606// GetOnuMetricsManager - TODO: add comment
4607func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4608 return dh.pOnuMetricsMgr
4609}
4610
4611// GetOnuTP - TODO: add comment
4612func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4613 return dh.pOnuTP
4614}
4615
4616// GetBackendPathPrefix - TODO: add comment
4617func (dh *deviceHandler) GetBackendPathPrefix() string {
4618 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4619}
4620
4621// GetOnuIndication - TODO: add comment
4622func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4623 return dh.pOnuIndication
4624}
4625
4626// RLockMutexDeletionInProgressFlag - TODO: add comment
4627func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4628 dh.mutexDeletionInProgressFlag.RLock()
4629}
4630
4631// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4632func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4633 dh.mutexDeletionInProgressFlag.RUnlock()
4634}
4635
4636// GetDeletionInProgress - TODO: add comment
4637func (dh *deviceHandler) GetDeletionInProgress() bool {
4638 return dh.deletionInProgress
4639}
4640
4641// GetPmConfigs - TODO: add comment
4642func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4643 return dh.pmConfigs
4644}
4645
4646// GetDeviceType - TODO: add comment
4647func (dh *deviceHandler) GetDeviceType() string {
4648 return dh.DeviceType
4649}
4650
4651// GetLogicalDeviceID - TODO: add comment
4652func (dh *deviceHandler) GetLogicalDeviceID() string {
4653 return dh.logicalDeviceID
4654}
4655
4656// GetDevice - TODO: add comment
4657func (dh *deviceHandler) GetDevice() *voltha.Device {
4658 return dh.device
4659}
4660
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004661func (dh *deviceHandler) setOltAvailable(value bool) {
4662 dh.mutexOltAvailable.Lock()
4663 dh.oltAvailable = value
4664 dh.mutexOltAvailable.Unlock()
4665}
4666
4667// IsOltAvailable - TODO: add comment
4668func (dh *deviceHandler) IsOltAvailable() bool {
4669 dh.mutexOltAvailable.RLock()
4670 defer dh.mutexOltAvailable.RUnlock()
4671 return dh.oltAvailable
4672}
4673
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004674// GetMetricsEnabled - TODO: add comment
4675func (dh *deviceHandler) GetMetricsEnabled() bool {
4676 return dh.pOpenOnuAc.MetricsEnabled
4677}
4678
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004679// GetExtendedOmciSupportEnabled - TODO: add comment
4680func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4681 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4682}
4683
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304684// GetExtendedOmciSupportEnabled - TODO: add comment
4685func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
4686 return dh.pOpenOnuAc.skipOnuConfig
4687}
4688
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004689// InitPmConfigs - TODO: add comment
4690func (dh *deviceHandler) InitPmConfigs() {
4691 dh.pmConfigs = &voltha.PmConfigs{}
4692}
4693
4694// GetUniPortMask - TODO: add comment
4695func (dh *deviceHandler) GetUniPortMask() int {
4696 return dh.pOpenOnuAc.config.UniPortMask
4697}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004698
4699func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4700 tpPathFound := false
4701 for _, tpPath := range aTpPathMap {
4702 if tpPath != "" {
4703 tpPathFound = true
4704 }
4705 }
4706 return tpPathFound
4707}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004708
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304709func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4710 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4711 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4712 return resp
4713}
4714
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05304715func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
4716 return dh.deviceDeleteCommChan
4717}
4718
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004719// PrepareForGarbageCollection - remove references to prepare for garbage collection
4720func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4721 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4722
4723 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4724 // first let the objects rest for some time to give all asynchronously started
4725 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004726 time.Sleep(2 * time.Second)
4727
4728 if dh.pOnuOmciDevice != nil {
4729 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4730 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4731 // reset handling (even in future coding), request monitoring is canceled here one last time to
4732 // be sure that all corresponding go routines are terminated
4733 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4734 }
4735 }
4736 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004737
4738 if dh.pOnuTP != nil {
4739 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4740 }
4741 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004742 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4743 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004744 select {
4745 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4746 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4747 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4748 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004749 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004750 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004751 }
4752 if dh.pAlarmMgr != nil {
4753 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4754 }
4755 if dh.pSelfTestHdlr != nil {
4756 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4757 }
4758 if dh.pLockStateFsm != nil {
4759 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4760 }
4761 if dh.pUnlockStateFsm != nil {
4762 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4763 }
4764 if dh.pOnuUpradeFsm != nil {
4765 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4766 }
4767 if dh.pOnuOmciDevice != nil {
4768 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4769 }
4770 for k, v := range dh.UniVlanConfigFsmMap {
4771 v.PrepareForGarbageCollection(ctx, aDeviceID)
4772 delete(dh.UniVlanConfigFsmMap, k)
4773 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05304774 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004775 dh.pOnuOmciDevice = nil
4776 dh.pOnuTP = nil
4777 dh.pOnuMetricsMgr = nil
4778 dh.pAlarmMgr = nil
4779 dh.pSelfTestHdlr = nil
4780 dh.pLockStateFsm = nil
4781 dh.pUnlockStateFsm = nil
4782 dh.pOnuUpradeFsm = nil
4783}