blob: e5cc1e0bb969f3fc1c56bd22d66595b6e550475e [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)
Akash Soni840f8d62024-12-11 19:37:06 +0530464 defer cancel2()
465 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
466 if err1 != nil {
467 logger.Errorf(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "error": err1})
468 return err
Girish Gowdra50e56422021-06-01 16:46:04 -0700469 }
470 return nil
471 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000472 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700473 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700474 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000477 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
478 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530479 return nil
480}
481
khenaidoo42dcdfd2021-10-19 17:34:12 -0400482func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000483 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530484
485 if dh.pOnuTP == nil {
486 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000488 log.Fields{"device-id": dh.DeviceID})
489 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530491 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 dh.pOnuTP.LockTpProcMutex()
493 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530494
mpagenko0f543222021-11-03 16:24:14 +0000495 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
496 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
497 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 }
501 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800503 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000504 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
505 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800506 return err
507 }
mpagenko0f543222021-11-03 16:24:14 +0000508 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
509 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000510 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000511
Mahir Gunyel9545be22021-07-04 15:53:16 -0700512 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
Himani Chawla26e555c2020-08-31 12:30:20 +0530515}
516
khenaidoo42dcdfd2021-10-19 17:34:12 -0400517func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000518 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 +0000519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000521 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
523 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530525 if dh.pOnuTP == nil {
526 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000527 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 log.Fields{"device-id": dh.DeviceID})
529 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530530 }
531
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 dh.pOnuTP.LockTpProcMutex()
534 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000535
mpagenko0f543222021-11-03 16:24:14 +0000536 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
537 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
538 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000541 }
542 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700543 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800545 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000546 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
547 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800548 return err
549 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530551
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000552 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
553 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530554 defer cancel()
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000555 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Akash Soni840f8d62024-12-11 19:37:06 +0530556 err1 := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
557 if err1 != nil {
558 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err1})
559 return err1
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000560 }
561
Mahir Gunyel9545be22021-07-04 15:53:16 -0700562 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000564
Mahir Gunyel9545be22021-07-04 15:53:16 -0700565}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000566
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
569 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700570 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
572 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700574 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 resourceName = "Gem"
577 } else {
578 resourceName = "Tcont"
579 }
580
581 // deadline context to ensure completion of background routines waited for
582 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
583 dctx, cancel := context.WithDeadline(context.Background(), deadline)
584
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700586
587 var wg sync.WaitGroup
588 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700590 resource, entryID, &wg)
591 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000592 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
593 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700594 return err
595 }
596
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
598 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
599 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
600 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700601 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +0530602 defer cancel2()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700603 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000604 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Akash Soni840f8d62024-12-11 19:37:06 +0530605 err := pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx))
606 if err != nil {
607 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID, "err": err})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700608 return err
609 }
610 }
611 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700613 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530614 return nil
615}
616
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530617// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000618func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400619 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400620 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700621 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
622 var errorsList []error
623 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000624 //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 +0000625 if apOfFlowChanges.ToRemove != nil {
626 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000627 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000628 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000629 "device-id": dh.DeviceID})
630 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700631 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000632 continue
633 }
634 flowInPort := flow.GetInPort(flowItem)
635 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000636 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
637 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700638 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000639 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000641 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000642 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000645 continue
646 } else {
647 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000649 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
650 loUniPort = uniPort
651 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000654 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000655 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700656 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000657 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000658 }
659 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
662 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700663
664 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
665 // Step1 : Fill flowControlBlock
666 // Step2 : Push the flowControlBlock to ONU channel
667 // Step3 : Wait on response channel for response
668 // Step4 : Return error value
669 startTime := time.Now()
670 respChan := make(chan error)
671 flowCb := FlowCb{
672 ctx: ctx,
673 addFlow: false,
674 flowItem: flowItem,
675 flowMetaData: nil,
676 uniPort: loUniPort,
677 respChan: &respChan,
678 }
679 dh.flowCbChan[loUniPort.UniID] <- flowCb
680 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
681 // Wait on the channel for flow handlers return value
682 retError = <-respChan
683 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
684 if retError != nil {
685 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
686 log.Fields{"device-id": dh.DeviceID, "error": retError})
687 errorsList = append(errorsList, retError)
688 continue
689 }
690 } else {
691 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
692 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000693 }
694 }
695 }
696 }
mpagenko01e726e2020-10-23 09:45:29 +0000697 if apOfFlowChanges.ToAdd != nil {
698 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
699 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000700 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000701 "device-id": dh.DeviceID})
702 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700703 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000704 continue
705 }
706 flowInPort := flow.GetInPort(flowItem)
707 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000708 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
709 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700710 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000711 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000713 } else if flowInPort == dh.ponPortNumber {
714 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000715 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000717 continue
718 } else {
719 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000721 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
722 loUniPort = uniPort
723 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000724 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000726 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000727 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700728 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000729 continue
mpagenko01e726e2020-10-23 09:45:29 +0000730 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000731 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
732 // if not, we just throw some error here to have an indication about that, if we really need to support that
733 // then we would need to create some means to activate the internal stored flows
734 // after the device gets active automatically (and still with its dependency to the TechProfile)
735 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
736 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000737 if !dh.IsReadyForOmciConfig() {
738 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
739 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700740 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
741 errorsList = append(errorsList, retError)
742 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000743 }
744
mpagenko01e726e2020-10-23 09:45:29 +0000745 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000747 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
748 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700749 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
750 // Step1 : Fill flowControlBlock
751 // Step2 : Push the flowControlBlock to ONU channel
752 // Step3 : Wait on response channel for response
753 // Step4 : Return error value
754 startTime := time.Now()
755 respChan := make(chan error)
756 flowCb := FlowCb{
757 ctx: ctx,
758 addFlow: true,
759 flowItem: flowItem,
760 flowMetaData: apFlowMetaData,
761 uniPort: loUniPort,
762 respChan: &respChan,
763 }
764 dh.flowCbChan[loUniPort.UniID] <- flowCb
765 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
766 // Wait on the channel for flow handlers return value
767 retError = <-respChan
768 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
769 if retError != nil {
770 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
771 log.Fields{"device-id": dh.DeviceID, "error": retError})
772 errorsList = append(errorsList, retError)
773 continue
774 }
775 } else {
776 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
777 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000778 }
779 }
780 }
781 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700782 if len(errorsList) > 0 {
783 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
784 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
785 }
786 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000787}
788
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530789// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
790// following are the expected device states after this activity:
791// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000792// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
794 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300795 dh.mutexForDisableDeviceRequested.Lock()
796 dh.disableDeviceRequested = true
797 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000798 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000799 //note that disableDevice sequences in some 'ONU active' state may yield also
800 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000801 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000802 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000803 //disable-device shall be just a UNi/ONU-G related admin state setting
804 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000805
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000807 // disable UNI ports/ONU
808 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
809 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000811 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000814 }
815 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000816 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000817 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000818 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400819 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000821 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400822 OperStatus: voltha.OperStatus_UNKNOWN,
823 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000824 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000826 }
mpagenko01e726e2020-10-23 09:45:29 +0000827 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000828
829 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000830 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000831 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300832 }
833}
834
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530835// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
837 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000838
mpagenkoaa3afe92021-05-21 16:20:58 +0000839 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000840 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
841 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
842 // for real ONU's that should have nearly no influence
843 // Note that for real ONU's there is anyway a problematic situation with following sequence:
844 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
845 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
846 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000847 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000848
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000849 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000850 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300851 dh.mutexForDisableDeviceRequested.Lock()
852 dh.disableDeviceRequested = false
853 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000854 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000856 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000859 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300860}
861
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530863 logger.Info(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000864
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000865 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000867 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868 return
869 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000870 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000871 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000872 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000873 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000875 }
mpagenko101ac942021-11-16 15:01:29 +0000876 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000877 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000878 }
Himani Chawla4d908332020-08-31 12:30:20 +0530879 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 pDevEntry.MutexPersOnuConfig.RLock()
881 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
882 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
883 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
884 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
885 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000887}
888
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000889func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530890 logger.Info(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000891
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000892 continueWithFlowConfig := false
893
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000895 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000896 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000897 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
898 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000899 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000900 dh.pOnuTP.LockTpProcMutex()
901 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000904 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000905 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
906 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530907 logger.Info(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000908 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000909 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
910 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000911 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000912 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700913 techProfsFound := false
914 techProfInstLoadFailed := false
915outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000916 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000917 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000918 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000919 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000920 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000921 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000922 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000923 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000924 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
925 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000926 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000928 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700929 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000930 var iaTechTpInst ia.TechProfileDownloadMessage
931 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800932 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000933 pDevEntry.MutexReconciledTpInstances.RLock()
934 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
935 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000936 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700938 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000939 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700940 break outerLoop
941 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000942 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000943 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700944 var tpInst tech_profile.TechProfileInstance
945 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400946 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000948 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000949 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000951 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
954 break outerLoop
955 }
956
Girish Gowdra041dcb32020-11-16 16:54:30 -0800957 // deadline context to ensure completion of background routines waited for
958 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
959 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000960 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000961
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800963 var wg sync.WaitGroup
964 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000966 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
968 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700969 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
970 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800971 }
mpagenko2dc896e2021-08-02 12:03:59 +0000972 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000973 if len(uniData.PersFlowParams) != 0 {
974 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000975 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000977 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 } // for all UNI entries from SOnuPersistentData
979 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
980 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000981 }
mpagenko2dc896e2021-08-02 12:03:59 +0000982
983 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
984 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000985
986 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000987}
988
989func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
990 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
991 if !abTechProfsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +0530992 logger.Warn(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000993 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000994 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 return
996 }
mpagenko2dc896e2021-08-02 12:03:59 +0000997 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000998 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000999 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001000 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001001 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001002 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 }
mpagenko2dc896e2021-08-02 12:03:59 +00001004 if !abFlowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301005 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001006 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001007 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001009}
1010
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001011func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1012 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001015 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001016 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001017 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001018 return
1019 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001021 pDevEntry.MutexPersOnuConfig.RLock()
1022 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1023 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301024 logger.Warn(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001026 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001027 return
1028 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001029 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001030 var uniVlanConfigEntries []uint8
1031 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1032
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001033 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001034 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1035 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001036 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001038 continue
1039 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001040 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001041 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001043 // It doesn't make sense to configure any flows if no TPs are available
1044 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001045 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001046 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1047 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001048 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001050
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001052 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001053 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001054 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1056 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001057 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001058 return
1059 }
mpagenko101ac942021-11-16 15:01:29 +00001060 //needed to split up function due to sca complexity
1061 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1062
mpagenko2dc896e2021-08-02 12:03:59 +00001063 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001064 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1066 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001067 // this can't be used as global finished reconciling flag because
1068 // assumes is getting called before the state machines for the last flow is completed,
1069 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001070 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1071 } // for all UNI entries from SOnuPersistentData
1072 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001073
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001074 if !flowsFound {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301075 logger.Warn(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001076 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001077 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001078 return
1079 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001080 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1081 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1082 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1083 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1084 log.Fields{"device-id": dh.DeviceID})
1085 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1086 if pDevEntry != nil {
1087 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001088 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001089 } else {
1090 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1091 log.Fields{"device-id": dh.DeviceID})
1092 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1093 if pDevEntry != nil {
1094 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1095 }
1096 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001097 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001098 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001099}
1100
mpagenko101ac942021-11-16 15:01:29 +00001101func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1102 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1103 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1104 flowsProcessed := 0
1105 lastFlowToReconcile := false
1106 loUniID := apUniPort.UniID
1107 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001108 if !(*apFlowsFound) {
1109 *apFlowsFound = true
1110 syncChannel := make(chan struct{})
1111 // start go routine with select() on reconciling vlan config channel before
1112 // starting vlan config reconciling process to prevent loss of any signal
1113 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1114 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1115 //block until the wait routine is really blocked on channel input
1116 // in order to prevent to early ready signal from VlanConfig processing
1117 <-syncChannel
1118 }
1119 if flowsProcessed == len(aPersFlowParam)-1 {
1120 var uniAdded bool
1121 lastFlowToReconcile = true
1122 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1123 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001124 }
1125 }
mpagenko101ac942021-11-16 15:01:29 +00001126 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1127 "device-id": dh.DeviceID, "uni-id": loUniID,
1128 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1129 dh.lockVlanConfig.Lock()
1130 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1131 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1132 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301133 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 +00001134 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1135 }
1136 } else {
1137 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301138 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301139 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, 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 }
1143 dh.lockVlanConfig.Unlock()
1144 flowsProcessed++
1145 } //for all flows of this UNI
1146}
1147
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301148// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1149//
1150// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001151func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1152 waitGroup *cmn.WaitGroupWithTimeOut) {
1153 var reconciledUniVlanConfigEntries []uint8
1154 var appended bool
1155 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1156 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1157 "device-id": dh.DeviceID, "expiry": expiry})
1158 // indicate blocking on channel now to the caller
1159 aSyncChannel <- struct{}{}
1160 for {
1161 select {
1162 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1163 switch uniIndication {
1164 // no activity requested (should normally not be received) - just continue waiting
1165 case cWaitReconcileFlowNoActivity:
1166 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1167 case cWaitReconcileFlowAbortOnError:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301168 logger.Warn(ctx, "waitReconcileFlow aborted on error",
mpagenko101ac942021-11-16 15:01:29 +00001169 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1170 return
1171 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1172 case cWaitReconcileFlowAbortOnSuccess:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301173 logger.Warn(ctx, "waitReconcileFlow aborted on success",
mpagenko101ac942021-11-16 15:01:29 +00001174 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1175 return
1176 // this should be a valid UNI vlan config done indication
1177 default:
1178 if uniIndication < platform.MaxUnisPerOnu {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301179 logger.Info(ctx, "reconciling flows has been finished in time for this UNI",
mpagenko101ac942021-11-16 15:01:29 +00001180 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1181 if reconciledUniVlanConfigEntries, appended =
1182 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1183 waitGroup.Done()
1184 }
1185 } else {
Akash Soni840f8d62024-12-11 19:37:06 +05301186 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored", log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
mpagenko101ac942021-11-16 15:01:29 +00001187 }
1188 } //switch uniIndication
1189
1190 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1191 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1192 log.Fields{"device-id": dh.DeviceID})
1193 return
1194 }
1195 }
1196}
1197
1198func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1199 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1200}
1201
1202func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1203 for _, ele := range slice {
1204 if ele == val {
1205 return slice, false
1206 }
1207 }
1208 return append(slice, val), true
1209}
1210
1211// sendChReconcileFinished - sends true or false on reconcileFinish channel
1212func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1213 if dh != nil { //if the object still exists (might have been already deleted in background)
1214 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1215 select {
1216 case dh.chReconcilingFinished <- success:
1217 default:
1218 }
1219 }
1220}
1221
1222// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1223func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1224 if dh != nil { //if the object still exists (might have been already deleted in background)
1225 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1226 select {
1227 case dh.chUniVlanConfigReconcilingDone <- value:
1228 default:
1229 }
1230 }
1231}
1232
dbainbri4d3a0dc2020-12-02 00:33:42 +00001233func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001235
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001237 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001238 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001240 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001241 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001242
1243 // deadline context to ensure completion of background routines waited for
1244 //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 +05301245 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246 dctx, cancel := context.WithDeadline(ctx, deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05301247 defer cancel()
1248 err := pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx))
1249 if err != nil {
1250 logger.Errorw(ctx, "delete data from onu kv store failed", log.Fields{"device-id": dh.DeviceID, "err": err})
1251 return err
1252 }
1253 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001254}
1255
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301256// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001257// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301258//
1259// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1260//
1261// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001262func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001264 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001266 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001267 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301269 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001270 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001271 return
Himani Chawla4d908332020-08-31 12:30:20 +05301272 }
mpagenko01e726e2020-10-23 09:45:29 +00001273
1274 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001276
mpagenko44bd8362021-11-15 11:40:05 +00001277 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001279 // 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 -04001280 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001282 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001283 OperStatus: voltha.OperStatus_DISCOVERED,
1284 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001285 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001287 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001288 }
mpagenkoe4782082021-11-25 12:04:26 +00001289 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001290 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001291 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001293 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1294 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1295 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1296 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001297}
1298
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301299// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1300//
1301// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001302func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001304 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001305 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001306
1307 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001309 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1311 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001312 }
1313
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001315 var inactiveImageID uint16
1316 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1317 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001318 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1319 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001320 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001321 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001322 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001323 if err == nil {
1324 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1325 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001326 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001327 }
1328 } else {
1329 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001330 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001331 }
mpagenko15ff4a52021-03-02 10:09:20 +00001332 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001333 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001335 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1336 dh.upgradeCanceled = true
1337 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1338 }
mpagenko38662d02021-08-11 09:45:19 +00001339 //no effort spent anymore for the old API to automatically cancel and restart the download
1340 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001341 }
mpagenko15ff4a52021-03-02 10:09:20 +00001342 } else {
1343 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001345 }
1346 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1348 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001349 }
1350 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001351}
1352
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301353// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001354// after the OnuImage has been downloaded to the adapter, called in background
1355func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001357
1358 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001360 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001362 return
1363 }
1364
1365 var inactiveImageID uint16
1366 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1367 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001369
mpagenko59862f02021-10-11 08:53:18 +00001370 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001372 // but must be still locked at calling createOnuUpgradeFsm
1373 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1374 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1375 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001376 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1377 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001378 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001379 //flush the remove upgradeFsmChan channel
1380 select {
1381 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001382 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001383 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001384 }
mpagenko59862f02021-10-11 08:53:18 +00001385 dh.lockUpgradeFsm.Unlock()
1386 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1387 dh.upgradeCanceled = true
1388 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1389 }
mpagenko38662d02021-08-11 09:45:19 +00001390 select {
1391 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001392 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001393 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1394 return
1395 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001396 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001397 }
mpagenko59862f02021-10-11 08:53:18 +00001398 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001399 }
mpagenko38662d02021-08-11 09:45:19 +00001400
1401 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001402 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001403 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001405 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001406 if err == nil {
1407 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1408 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1409 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001411 return
1412 }
mpagenko38662d02021-08-11 09:45:19 +00001413 } else {
1414 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001415 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001416 }
1417 return
1418 }
1419 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001421}
1422
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301423// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001424func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1425 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001426 var err error
1427 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1428 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1429 // 2.) activation of the inactive image
1430
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001433 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1434 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001435 }
1436 dh.lockUpgradeFsm.RLock()
1437 if dh.pOnuUpradeFsm != nil {
1438 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001439 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1442 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 }
mpagenko59862f02021-10-11 08:53:18 +00001444 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1445 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1446 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1447 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001448 // use the OnuVendor identification from this device for the internal unique name
1449 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001450 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001452 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001453 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001454 "device-id": dh.DeviceID, "error": err})
1455 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001456 }
mpagenko183647c2021-06-08 15:25:04 +00001457 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001458 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001459 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001460 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001461 } //else
1462 dh.lockUpgradeFsm.RUnlock()
1463
1464 // 2.) check if requested image-version equals the inactive one and start its activation
1465 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1466 var inactiveImageID uint16
1467 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1468 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001469 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1470 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001471 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001472 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001474 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001475 if err == nil {
1476 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1477 inactiveImageID, aCommitRequest); err != nil {
1478 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001479 "device-id": dh.DeviceID, "error": err})
1480 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001481 }
1482 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001483 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001484 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001485 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001486 } //else
1487 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 "device-id": dh.DeviceID, "error": err})
1489 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001490}
1491
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301492// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001493func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1494 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001495 var err error
1496 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1497 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1498 // 2.) commitment of the active image
1499
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001502 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1503 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001504 }
1505 dh.lockUpgradeFsm.RLock()
1506 if dh.pOnuUpradeFsm != nil {
1507 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001509 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001510 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1511 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 }
mpagenko59862f02021-10-11 08:53:18 +00001513 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1514 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1515 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1516 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001517 // use the OnuVendor identification from this device for the internal unique name
1518 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001519 // 1.) check a started upgrade process and relay the commitment request to it
1520 // the running upgrade may be based either on the imageIdentifier (started from download)
1521 // or on the imageVersion (started from pure activation)
1522 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1523 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001524 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001525 "device-id": dh.DeviceID, "error": err})
1526 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001527 }
mpagenko183647c2021-06-08 15:25:04 +00001528 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001530 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001531 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001532 } //else
1533 dh.lockUpgradeFsm.RUnlock()
1534
mpagenko183647c2021-06-08 15:25:04 +00001535 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001536 var activeImageID uint16
1537 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1538 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001539 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1540 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001541 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001542 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001543 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001544 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001545 if err == nil {
1546 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1547 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001548 "device-id": dh.DeviceID, "error": err})
1549 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001550 }
1551 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001552 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001553 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001554 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001555 } //else
1556 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001557 "device-id": dh.DeviceID, "error": err})
1558 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001559}
1560
mpagenkoaa3afe92021-05-21 16:20:58 +00001561func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001562 aVersion string) *voltha.ImageState {
1563 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001564 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001565 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001566 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001567 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1568 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1569 if aVersion == dh.pLastUpgradeImageState.Version {
1570 pImageState = dh.pLastUpgradeImageState
1571 } else { //state request for an image version different from last processed image version
1572 pImageState = &voltha.ImageState{
1573 Version: aVersion,
1574 //we cannot state something concerning this version
1575 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1576 Reason: voltha.ImageState_NO_ERROR,
1577 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1578 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001579 }
1580 }
mpagenko38662d02021-08-11 09:45:19 +00001581 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001582}
1583
1584func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1585 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001587 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001588 dh.lockUpgradeFsm.RLock()
1589 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001590 dh.lockUpgradeFsm.RUnlock()
1591 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001592 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001593 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1594 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1595 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1596 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1597 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1598 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001599 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1600 dh.upgradeCanceled = true
1601 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1602 }
mpagenko45586762021-10-01 08:30:22 +00001603 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001604 } else {
mpagenko45586762021-10-01 08:30:22 +00001605 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001606 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1607 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1608 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1609 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1610 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1611 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001612 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1613 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001614 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1615 //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 +00001616 }
1617}
1618
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001619func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1620
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001624 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1626 pDevEntry.MutexOnuImageStatus.Lock()
1627 pDevEntry.POnuImageStatus = onuImageStatus
1628 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001629
1630 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001632 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1635 pDevEntry.MutexOnuImageStatus.Lock()
1636 pDevEntry.POnuImageStatus = nil
1637 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001638 return images, err
1639}
1640
Himani Chawla6d2ae152020-09-02 13:11:20 +05301641// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642// #####################################################################################
1643
1644// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301645// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001648 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1649 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650}
1651
1652// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001655 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 var err error
1657
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658 // populate what we know. rest comes later after mib sync
1659 dh.device.Root = false
1660 dh.device.Vendor = "OpenONU"
1661 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001663 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001666
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 if !dh.IsReconciling() {
1668 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001669 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1670 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1671 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301672 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001673 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301674 logger.Infow(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001676 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677
Himani Chawla4d908332020-08-31 12:30:20 +05301678 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001679 dh.ponPortNumber = dh.device.ParentPortNo
1680
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1682 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1683 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301686 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687
1688 /*
1689 self._pon = PonPort.create(self, self._pon_port_number)
1690 self._pon.add_peer(self.parent_id, self._pon_port_number)
1691 self.logger.debug('adding-pon-port-to-agent',
1692 type=self._pon.get_port().type,
1693 admin_state=self._pon.get_port().admin_state,
1694 oper_status=self._pon.get_port().oper_status,
1695 )
1696 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 if !dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301698 logger.Infow(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001699 var ponPortNo uint32 = 1
1700 if dh.ponPortNumber != 0 {
1701 ponPortNo = dh.ponPortNumber
1702 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001703
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001704 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001705 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001706 PortNo: ponPortNo,
1707 Label: fmt.Sprintf("pon-%d", ponPortNo),
1708 Type: voltha.Port_PON_ONU,
1709 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301710 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001711 PortNo: ponPortNo}}, // Peer port is parent's port number
1712 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001713 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001714 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001715 e.Cancel(err)
1716 return
1717 }
1718 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301719 logger.Infow(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001721 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722}
1723
1724// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001727 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 var err error
1729 /*
1730 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1731 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1732 return nil
1733 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001735 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001736 e.Cancel(err)
1737 return
1738 }
1739
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001742 // reconcilement will be continued after mib download is done
1743 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001744
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001745 /*
1746 ############################################################################
1747 # Setup Alarm handler
1748 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1749 device.serial_number)
1750 ############################################################################
1751 # Setup PM configuration for this device
1752 # Pass in ONU specific options
1753 kwargs = {
1754 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1755 'heartbeat': self.heartbeat,
1756 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1757 }
1758 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1759 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1760 self.logical_device_id, device.serial_number,
1761 grouped=True, freq_override=False, **kwargs)
1762 pm_config = self._pm_metrics.make_proto()
1763 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1764 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1765 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1766
1767 # Note, ONU ID and UNI intf set in add_uni_port method
1768 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1769 ani_ports=[self._pon])
1770
1771 # Code to Run OMCI Test Action
1772 kwargs_omci_test_action = {
1773 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1774 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1775 }
1776 serial_number = device.serial_number
1777 self._test_request = OmciTestRequest(self.core_proxy,
1778 self.omci_agent, self.device_id,
1779 AniG, serial_number,
1780 self.logical_device_id,
1781 exclusive=False,
1782 **kwargs_omci_test_action)
1783
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001784 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001785 else:
1786 self.logger.info('onu-already-activated')
1787 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001788
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001789 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001790}
1791
1792// doStateConnected get the device info and update to voltha core
1793// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301794//
1795// voltha-openolt-adapter/adaptercore/device_handler.go
1796// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001798
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001799 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301800 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001801 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001802 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001803}
1804
1805// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001808 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301809 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001810 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001811 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001812
1813 /*
1814 // Synchronous call to update device state - this method is run in its own go routine
1815 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1816 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001817 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 +00001818 return err
1819 }
1820 return nil
1821 */
1822}
1823
1824// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001826
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001827 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 var err error
1829
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001830 device := dh.device
1831 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001832 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001833 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 e.Cancel(err)
1835 return
1836 }
1837
1838 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001840 /*
1841 // Update the all ports state on that device to disable
1842 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001843 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001844 return er
1845 }
1846
1847 //Update the device oper state and connection status
1848 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1849 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1850 dh.device = cloned
1851
1852 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001853 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001854 return er
1855 }
1856
1857 //get the child device for the parent device
1858 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1859 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001860 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001861 return err
1862 }
1863 for _, onuDevice := range onuDevices.Items {
1864
1865 // Update onu state as down in onu adapter
1866 onuInd := oop.OnuIndication{}
1867 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001868 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1870 if er != nil {
1871 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001872 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001873 //Do not return here and continue to process other ONUs
1874 }
1875 }
1876 // * Discovered ONUs entries need to be cleared , since after OLT
1877 // is up, it starts sending discovery indications again* /
1878 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001879 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880 return nil
1881 */
Himani Chawla4d908332020-08-31 12:30:20 +05301882 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001883 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001884 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885}
1886
Himani Chawla6d2ae152020-09-02 13:11:20 +05301887// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001888// #################################################################################
1889
1890// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301891// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001892
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301893// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001894func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001895 dh.lockDevice.RLock()
1896 pOnuDeviceEntry := dh.pOnuOmciDevice
1897 if aWait && pOnuDeviceEntry == nil {
1898 //keep the read sema short to allow for subsequent write
1899 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001900 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001901 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1902 // so it might be needed to wait here for that event with some timeout
1903 select {
1904 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001905 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001906 return nil
1907 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001909 // if written now, we can return the written value without sema
1910 return dh.pOnuOmciDevice
1911 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001912 }
mpagenko3af1f032020-06-10 08:53:41 +00001913 dh.lockDevice.RUnlock()
1914 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001915}
1916
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301917// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001918func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1919 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001920 dh.lockDevice.Lock()
1921 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001922 dh.pOnuOmciDevice = apDeviceEntry
1923 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001924 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301925 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001926 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001927}
1928
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301929// addOnuDeviceEntry creates a new ONU device or returns the existing
Himani Chawla6d2ae152020-09-02 13:11:20 +05301930func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001931 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001932
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001933 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001934 if deviceEntry == nil {
1935 /* costum_me_map in python code seems always to be None,
1936 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1937 /* also no 'clock' argument - usage open ...*/
1938 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1940 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1941 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1942 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1943 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001944 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001945 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001946 // fire deviceEntry ready event to spread to possibly waiting processing
1947 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001948 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001951 }
1952 // might be updated with some error handling !!!
1953 return nil
1954}
1955
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001957 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001958 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1959
1960 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001961
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001962 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001963 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1965 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001966 }
praneeth.nalmas2d75f002023-03-31 12:59:59 +05301967
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 if !dh.IsReconciling() {
1969 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001972 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001975
khenaidoo42dcdfd2021-10-19 17:34:12 -04001976 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001977 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001978 OperStatus: voltha.OperStatus_ACTIVATING,
1979 ConnStatus: voltha.ConnectStatus_REACHABLE,
1980 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001981 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001983 }
1984 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05301985 logger.Info(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001986 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001987
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 pDevEntry.MutexPersOnuConfig.RLock()
1989 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1990 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 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 +00001992 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001993 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05301994
1995 //VOL-4965: Recover previously Activating ONU during reconciliation.
1996 if dh.device.OperStatus == common.OperStatus_ACTIVATING {
1997 logger.Debugw(ctx, "Reconciling an ONU in previously activating state, perform MIB reset and resume normal start up",
1998 log.Fields{"device-id": dh.DeviceID})
1999 pDevEntry.MutexPersOnuConfig.Lock()
2000 pDevEntry.SOnuPersistentData.PersMibLastDbSync = 0
2001 pDevEntry.MutexPersOnuConfig.Unlock()
2002 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002003 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002004 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002005 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002006 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002007 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2008 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2009 // 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 +00002010 // 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 +00002011 // so let's just try to keep it simple ...
2012 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002014 if err != nil || device == nil {
2015 //TODO: needs to handle error scenarios
2016 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2017 return errors.New("Voltha Device not found")
2018 }
2019 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002021 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002022 return err
mpagenko3af1f032020-06-10 08:53:41 +00002023 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002024 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302025 if !dh.IsReconciling() && !dh.GetSkipOnuConfigEnabled() {
2026 /* this might be a good time for Omci Verify message? */
2027 verifyExec := make(chan bool)
2028 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
2029 dh.device.Id, pDevEntry.PDevOmciCC, false,
2030 true, true) //exclusive and allowFailure (anyway not yet checked)
2031 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002032
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05302033 /* give the handler some time here to wait for the OMCi verification result
2034 after Timeout start and try MibUpload FSM anyway
2035 (to prevent stopping on just not supported OMCI verification from ONU) */
2036 select {
2037 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
2038 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
2039 case testresult := <-verifyExec:
2040 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
2041 case <-dh.deviceDeleteCommChan:
2042 logger.Warnw(ctx, "Deleting device, stopping the omci test activity", log.Fields{"device-id": dh.DeviceID})
2043 return nil
2044 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002045 }
2046
2047 /* In py code it looks earlier (on activate ..)
2048 # Code to Run OMCI Test Action
2049 kwargs_omci_test_action = {
2050 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2051 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2052 }
2053 serial_number = device.serial_number
2054 self._test_request = OmciTestRequest(self.core_proxy,
2055 self.omci_agent, self.device_id,
2056 AniG, serial_number,
2057 self.logical_device_id,
2058 exclusive=False,
2059 **kwargs_omci_test_action)
2060 ...
2061 # Start test requests after a brief pause
2062 if not self._test_request_started:
2063 self._test_request_started = True
2064 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2065 reactor.callLater(tststart, self._test_request.start_collector)
2066
2067 */
2068 /* which is then: in omci_test_request.py : */
2069 /*
2070 def start_collector(self, callback=None):
2071 """
2072 Start the collection loop for an adapter if the frequency > 0
2073
2074 :param callback: (callable) Function to call to collect PM data
2075 """
2076 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2077 if callback is None:
2078 callback = self.perform_test_omci
2079
2080 if self.lc is None:
2081 self.lc = LoopingCall(callback)
2082
2083 if self.default_freq > 0:
2084 self.lc.start(interval=self.default_freq / 10)
2085
2086 def perform_test_omci(self):
2087 """
2088 Perform the initial test request
2089 """
2090 ani_g_entities = self._device.configuration.ani_g_entities
2091 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2092 is not None else None
2093 self._entity_id = ani_g_entities_ids[0]
2094 self.logger.info('perform-test', entity_class=self._entity_class,
2095 entity_id=self._entity_id)
2096 try:
2097 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2098 result = yield self._device.omci_cc.send(frame)
2099 if not result.fields['omci_message'].fields['success_code']:
2100 self.logger.info('Self-Test Submitted Successfully',
2101 code=result.fields[
2102 'omci_message'].fields['success_code'])
2103 else:
2104 raise TestFailure('Test Failure: {}'.format(
2105 result.fields['omci_message'].fields['success_code']))
2106 except TimeoutError as e:
2107 self.deferred.errback(failure.Failure(e))
2108
2109 except Exception as e:
2110 self.logger.exception('perform-test-Error', e=e,
2111 class_id=self._entity_class,
2112 entity_id=self._entity_id)
2113 self.deferred.errback(failure.Failure(e))
2114
2115 */
2116
2117 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002118 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002119
mpagenko1cc3cb42020-07-27 15:24:38 +00002120 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2121 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2122 * 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 +05302123 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002124 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002125 //call MibUploadFSM - transition up to state UlStInSync
2126 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002127 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 if pMibUlFsm.Is(mib.UlStDisabled) {
2129 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2130 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2131 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302132 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002133 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302134 //Determine ONU status and start/re-start MIB Synchronization tasks
2135 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 if pDevEntry.IsNewOnu() {
2137 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2138 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2139 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140 }
Himani Chawla4d908332020-08-31 12:30:20 +05302141 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002142 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2143 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2144 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302145 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002146 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002147 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002148 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002150 "device-id": dh.DeviceID})
2151 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002152 }
2153 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002154 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2155 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002156 }
2157 return nil
2158}
2159
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002160func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002161 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002162 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302164 logger.Info(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002165
mpagenko900ee4b2020-10-12 11:56:34 +00002166 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2167 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2168 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002169 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002171 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002172 // abort: system behavior is just unstable ...
2173 return err
2174 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002175 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 _ = 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 +00002177
2178 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002179 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002180 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002181 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2183 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002184 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002186
2187 //TODO!!! remove existing traffic profiles
2188 /* from py code, if TP's exist, remove them - not yet implemented
2189 self._tp = dict()
2190 # Let TP download happen again
2191 for uni_id in self._tp_service_specific_task:
2192 self._tp_service_specific_task[uni_id].clear()
2193 for uni_id in self._tech_profile_download_done:
2194 self._tech_profile_download_done[uni_id].clear()
2195 */
2196
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002198
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002199 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002200
mpagenkoe4782082021-11-25 12:04:26 +00002201 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002202 // abort: system behavior is just unstable ...
2203 return err
2204 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002207 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002208 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002209 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2210 OperStatus: voltha.OperStatus_DISCOVERED,
2211 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002212 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002214 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002215 // abort: system behavior is just unstable ...
2216 return err
2217 }
2218 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002220 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002221 return nil
2222}
2223
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002224func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002225 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2226 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2227 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2228 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002229 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002230
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302232 //VOL-5260: During race conditions when adoptDevice has not yet completed
2233 // and deleteDevice is issued , returning error will further prevent clean up
2234 // at rwcore . Returning success for clean up to happen and discovery to happen again.
mpagenko900ee4b2020-10-12 11:56:34 +00002235 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
Praneeth Kumar Nalmasfcdd20b2024-01-24 22:26:39 +05302237 return nil
mpagenko900ee4b2020-10-12 11:56:34 +00002238 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002239 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002240 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002241 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 pDevEntry.MutexOnuImageStatus.RLock()
2243 if pDevEntry.POnuImageStatus != nil {
2244 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002245 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002247
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002248 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002249 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002250 }
2251 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002252 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002253 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002255 }
mpagenko101ac942021-11-16 15:01:29 +00002256 //stop any deviceHandler reconcile processing (if running)
2257 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002258 //port lock/unlock FSM's may be active
2259 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002261 }
2262 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002264 }
2265 //techProfile related PonAniConfigFsm FSM may be active
2266 if dh.pOnuTP != nil {
2267 // should always be the case here
2268 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002269 if dh.pOnuTP.PAniConfigFsm != nil {
2270 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2271 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002272 }
mpagenko900ee4b2020-10-12 11:56:34 +00002273 }
2274 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002275 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002276 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002278 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002279 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002280 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002281 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002282 } else {
2283 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002284 }
2285 }
2286 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302287
2288 dh.mutexCollectorFlag.Lock()
2289 logger.Debugw(ctx, "check-collector-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.collectorIsRunning})
2290 if dh.collectorIsRunning {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002291 // Stop collector routine
2292 dh.stopCollector <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302293 dh.collectorIsRunning = false
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002294 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302295 dh.mutexCollectorFlag.Unlock()
2296
2297 dh.mutextAlarmManagerFlag.Lock()
2298 logger.Debugw(ctx, "check-alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
2299 if dh.alarmManagerIsRunning {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302300 dh.stopAlarmManager <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302301 dh.alarmManagerIsRunning = false
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302302 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302303 dh.mutextAlarmManagerFlag.Unlock()
2304
2305 dh.pSelfTestHdlr.SelfTestHandlerLock.Lock()
2306 logger.Debugw(ctx, "check-self-test-control-block-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.pSelfTestHdlr.SelfTestHandlerActive})
2307 if dh.pSelfTestHdlr.SelfTestHandlerActive {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002308 dh.pSelfTestHdlr.StopSelfTestModule <- true
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302309 dh.pSelfTestHdlr.SelfTestHandlerActive = false
Girish Gowdra10123c02021-08-30 11:52:06 -07002310 }
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05302311 dh.pSelfTestHdlr.SelfTestHandlerLock.Unlock()
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302312
Girish Gowdrae95687a2021-09-08 16:30:58 -07002313 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2314
mpagenko80622a52021-02-09 16:53:23 +00002315 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002317 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002318 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002319 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002320 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002321 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002322 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2323 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2324 // (even though it may also run into direct cancellation, a bit hard to verify here)
2325 // so don't set 'dh.upgradeCanceled = true' here!
2326 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2327 }
mpagenko38662d02021-08-11 09:45:19 +00002328 }
mpagenko80622a52021-02-09 16:53:23 +00002329
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002331 return nil
2332}
2333
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2335 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 +05302336
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002337 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002339 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002341 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002342 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002343 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002344
mpagenkoa40e99a2020-11-17 13:50:39 +00002345 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2346 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2347 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2348 * disable/enable toggling here to allow traffic
2349 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2350 * like the py comment says:
2351 * # start by locking all the unis till mib sync and initial mib is downloaded
2352 * # this way we can capture the port down/up events when we are ready
2353 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302354
mpagenkoa40e99a2020-11-17 13:50:39 +00002355 // Init Uni Ports to Admin locked state
2356 // *** should generate UniLockStateDone event *****
2357 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002358 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002359 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002360 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002362 }
2363}
2364
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2366 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302367 /* Mib download procedure -
2368 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2369 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002370 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002371 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002372 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002373 return
2374 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002377 if pMibDlFsm.Is(mib.DlStDisabled) {
2378 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2379 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 +05302380 // maybe try a FSM reset and then again ... - TODO!!!
2381 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002382 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302383 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2385 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302386 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002387 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302388 //Begin MIB data download (running autonomously)
2389 }
2390 }
2391 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002392 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302394 // maybe try a FSM reset and then again ... - TODO!!!
2395 }
2396 /***** Mib download started */
2397 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302399 }
2400}
2401
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002402func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302403 logger.Info(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002404 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2405 if pDevEntry == nil {
2406 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2407 return
2408 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002410 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002412 // update device info in core
2413 pDevEntry.MutexPersOnuConfig.RLock()
2414 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2415 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2416 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2417 pDevEntry.MutexPersOnuConfig.RUnlock()
2418 dh.logicalDeviceID = dh.DeviceID
2419 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2420 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2421 }
2422 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002423 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2424 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2425 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2426 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002427 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002428 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002429 ConnStatus: voltha.ConnectStatus_REACHABLE,
2430 OperStatus: voltha.OperStatus_ACTIVE,
2431 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302432 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002433 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302434 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002435 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302436 }
2437 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302438 logger.Info(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002439 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302440 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002441 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002444 var waitForOmciProcessor sync.WaitGroup
2445 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002446 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002447 go dh.StartCollector(ctx, &waitForOmciProcessor)
2448 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 if !dh.GetAlarmManagerIsRunning(ctx) {
2451 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002452 }
2453
Girish Gowdrae95687a2021-09-08 16:30:58 -07002454 // Start flow handler routines per UNI
2455 for _, uniPort := range dh.uniEntityMap {
2456 // only if this port was enabled for use by the operator at startup
2457 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2458 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2459 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2460 }
2461 }
2462 }
2463
Girish Gowdrae0140f02021-02-02 16:55:09 -08002464 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002465 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002466 // There is no way we should be landing here, but if we do then
2467 // there is nothing much we can do about this other than log error
2468 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2469 }
2470
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002471 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002472
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 pDevEntry.MutexPersOnuConfig.RLock()
2474 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2475 pDevEntry.MutexPersOnuConfig.RUnlock()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302476 logger.Warn(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002478 dh.mutexForDisableDeviceRequested.Lock()
2479 dh.disableDeviceRequested = true
2480 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002481 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002482 // reconcilement will be continued after ani config is done
2483 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002485 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002486 dh.mutexForDisableDeviceRequested.RLock()
2487 if !dh.disableDeviceRequested {
2488 if dh.pUnlockStateFsm == nil {
2489 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2490 } else { //UnlockStateFSM already init
2491 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2492 dh.runUniLockFsm(ctx, false)
2493 }
2494 dh.mutexForDisableDeviceRequested.RUnlock()
2495 } else {
2496 dh.mutexForDisableDeviceRequested.RUnlock()
2497 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002498 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302499 }
2500}
2501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2503 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302504
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 if !dh.IsReconciling() {
2506 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002507 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2509 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002510 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002511 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002512 return
2513 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002514 pDevEntry.MutexPersOnuConfig.Lock()
2515 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2516 pDevEntry.MutexPersOnuConfig.Unlock()
2517 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002518 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002520 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302521 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302522 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 +00002523 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002524 dh.ReconcileDeviceTechProf(ctx)
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302525
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002526 // reconcilement will be continued after ani config is done
praneeth.nalmas2d75f002023-03-31 12:59:59 +05302527
Himani Chawla26e555c2020-08-31 12:30:20 +05302528 }
2529}
2530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002532 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002534
mpagenko44bd8362021-11-15 11:40:05 +00002535 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002536 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002538 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002539 OperStatus: voltha.OperStatus_UNKNOWN,
2540 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002541 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002543 }
2544
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002546 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002547 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002548
2549 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002550 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002553 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002555 return
2556 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 pDevEntry.MutexPersOnuConfig.Lock()
2558 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2559 pDevEntry.MutexPersOnuConfig.Unlock()
2560 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002561 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002563 }
mpagenko900ee4b2020-10-12 11:56:34 +00002564}
2565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002566func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002568 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002569 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002571 ConnStatus: voltha.ConnectStatus_REACHABLE,
2572 OperStatus: voltha.OperStatus_ACTIVE,
2573 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002574 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002576 }
2577
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002579 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002580 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002581 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002582
2583 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002586 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002587 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002589 return
2590 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 pDevEntry.MutexPersOnuConfig.Lock()
2592 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2593 pDevEntry.MutexPersOnuConfig.Unlock()
2594 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002595 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002597 }
mpagenko900ee4b2020-10-12 11:56:34 +00002598}
2599
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002600func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2601 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2602 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002603 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002604 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002605 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002606 OperStatus: voltha.OperStatus_FAILED,
2607 }); err != nil {
2608 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2609 }
2610}
2611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002612func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2613 if devEvent == cmn.OmciAniConfigDone {
2614 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002615 // attention: the device reason update is done based on ONU-UNI-Port related activity
2616 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002618 // 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 +00002619 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302620 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002622 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2623 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2624 dh.mutexReconcilingFirstPassFlag.Lock()
2625 if dh.reconcilingFirstPass {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302626 logger.Info(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002627 dh.reconcilingFirstPass = false
2628 go dh.ReconcileDeviceFlowConfig(ctx)
2629 }
2630 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002631 }
2632 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002634 // attention: the device reason update is done based on ONU-UNI-Port related activity
2635 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002637 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2638 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002639 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002640 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302641}
2642
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002644 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002645 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302646 // attention: the device reason update is done based on ONU-UNI-Port related activity
2647 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302648
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2650 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002651 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002652 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002653 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002654 }
2655 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002657 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002658 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002659 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302660 }
mpagenkof1fc3862021-02-16 10:09:52 +00002661
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002663 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002664 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002665 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002667 }
2668 } else {
2669 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002670 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002671 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302672}
2673
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302674// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302676 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002678 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002679 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002680 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002681 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002682 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002683 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002684 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002686 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002687 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002688 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002690 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002691 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002692 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002694 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002695 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002696 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002697 case cmn.UniEnableStateFailed:
2698 {
2699 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2700 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002702 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002703 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002706 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002707 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002708 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002710 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002711 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002712 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002713 default:
2714 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002716 }
2717 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002718}
2719
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002721 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002722 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302723 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002724 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002725 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002726 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302727 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002729 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002730 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 +00002731 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002732 //store UniPort with the System-PortNumber key
2733 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002735 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002737 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002738 } //error logging already within UniPort method
2739 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302740 logger.Warn(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002741 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002742 }
2743 }
2744}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002745
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2747 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002748 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002749 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002750 return
2751 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002752 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002754 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2755 for _, mgmtEntityID := range pptpInstKeys {
2756 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002758 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2759 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002760 }
2761 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002763 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002765 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2766 for _, mgmtEntityID := range veipInstKeys {
2767 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002768 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002769 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2770 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002771 }
2772 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002774 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002776 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2777 for _, mgmtEntityID := range potsInstKeys {
2778 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002780 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2781 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002782 }
2783 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002785 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002786 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002788 return
2789 }
2790
mpagenko2c3f6c52021-11-23 11:22:10 +00002791 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2792 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2793 // 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 -07002794 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2795 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2796 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002797 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2798 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002799 for i := 0; i < int(uniCnt); i++ {
2800 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002801 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002802 }
2803}
2804
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002805// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2806func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002807 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302808 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002809 // with following remark:
2810 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2811 // # load on the core
2812
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002813 // 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 +00002814
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002815 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002816 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002817 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2818 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2819 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2820 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002821 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002822 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002823 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002824 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002825 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826 PortNo: port.PortNo,
2827 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002828 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002829 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 -04002830 }
2831 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002832 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302833 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002834 }
mpagenko3af1f032020-06-10 08:53:41 +00002835 }
2836 }
2837}
2838
2839// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002840func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2841 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002842 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2843 for uniNo, uniPort := range dh.uniEntityMap {
2844 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002845
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2847 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2848 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2849 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002850 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002852 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002854 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 PortNo: port.PortNo,
2856 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002857 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 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 -04002859 }
2860 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002861 } else {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302862 logger.Debug(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002863 }
2864
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002865 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002866 }
2867}
2868
2869// ONU_Active/Inactive announcement on system KAFKA bus
2870// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002872 var de voltha.DeviceEvent
2873 eventContext := make(map[string]string)
2874 //Populating event context
2875 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002876 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002877 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002878 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002879 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002880 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 +00002881 }
2882 oltSerialNumber := parentDevice.SerialNumber
2883
2884 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2885 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2886 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302887 eventContext["olt-serial-number"] = oltSerialNumber
2888 eventContext["device-id"] = aDeviceID
2889 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002890 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002891 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2892 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002893 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2894 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2896 deviceEntry.MutexPersOnuConfig.RUnlock()
2897 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002898 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002899 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2900 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2901 } else {
2902 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2903 log.Fields{"device-id": aDeviceID})
2904 return
2905 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002906
2907 /* Populating device event body */
2908 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302909 de.ResourceId = aDeviceID
2910 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002911 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2912 de.Description = fmt.Sprintf("%s Event - %s - %s",
2913 cEventObjectType, cOnuActivatedEvent, "Raised")
2914 } else {
2915 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2916 de.Description = fmt.Sprintf("%s Event - %s - %s",
2917 cEventObjectType, cOnuActivatedEvent, "Cleared")
2918 }
2919 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302920 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002921 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302922 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002923 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05302924 logger.Infow(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302925 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002926}
2927
Himani Chawla4d908332020-08-31 12:30:20 +05302928// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05302930 chLSFsm := make(chan cmn.Message, 2)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002931 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302932 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002933 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002934 sFsmName = "LockStateFSM"
2935 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002937 sFsmName = "UnLockStateFSM"
2938 }
mpagenko3af1f032020-06-10 08:53:41 +00002939
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002941 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002943 return
2944 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002946 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302947 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002948 dh.pLockStateFsm = pLSFsm
2949 } else {
2950 dh.pUnlockStateFsm = pLSFsm
2951 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002953 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002955 }
2956}
2957
2958// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002959func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002960 /* Uni Port lock/unlock procedure -
2961 ***** should run via 'adminDone' state and generate the argument requested event *****
2962 */
2963 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302964 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002965 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002966 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2967 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2969 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002970 }
2971 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002973 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2974 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2976 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002977 }
2978 }
2979 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002980 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2981 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002982 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002983 // maybe try a FSM reset and then again ... - TODO!!!
2984 } else {
2985 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002986 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002987 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002988 }
2989 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002990 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002992 // maybe try a FSM reset and then again ... - TODO!!!
2993 }
2994 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002995 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002996 // maybe try a FSM reset and then again ... - TODO!!!
2997 }
2998}
2999
mpagenko80622a52021-02-09 16:53:23 +00003000// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00003001// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003002func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303003 chUpgradeFsm := make(chan cmn.Message, 2)
mpagenko80622a52021-02-09 16:53:23 +00003004 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003006 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003008 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00003009 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003010 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00003011 sFsmName, chUpgradeFsm)
3012 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003014 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
3016 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003017 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00003018 // maybe try a FSM reset and then again ... - TODO!!!
3019 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
3020 }
mpagenko59862f02021-10-11 08:53:18 +00003021 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00003022 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
3023 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00003024 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
3025 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00003026 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003027 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003028 } else {
3029 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003031 // maybe try a FSM reset and then again ... - TODO!!!
3032 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
3033 }
3034 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003036 // maybe try a FSM reset and then again ... - TODO!!!
3037 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
3038 }
3039 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003040 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003041 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3042 }
3043 return nil
3044}
3045
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3047func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003048 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003049 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003050 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003051 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3052 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003053 dh.pLastUpgradeImageState = apImageState
3054 dh.lockUpgradeFsm.Unlock()
3055 //signal upgradeFsm removed using non-blocking channel send
3056 select {
3057 case dh.upgradeFsmChan <- struct{}{}:
3058 default:
3059 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003061 }
mpagenko80622a52021-02-09 16:53:23 +00003062}
3063
mpagenko15ff4a52021-03-02 10:09:20 +00003064// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3065func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003067 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003069 return
3070 }
3071
3072 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003073 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003074 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003075 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3076 dh.lockUpgradeFsm.RUnlock()
3077 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3078 return
3079 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003081 if pUpgradeStatemachine != nil {
3082 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3083 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084 UpgradeState := pUpgradeStatemachine.Current()
3085 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3086 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3087 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003088 // 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 +00003089 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003090 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3091 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003092 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003093 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003095 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3096 dh.upgradeCanceled = true
3097 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3098 }
mpagenko15ff4a52021-03-02 10:09:20 +00003099 return
3100 }
mpagenko59862f02021-10-11 08:53:18 +00003101 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003102 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3103 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003104 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003105 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003106 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3107 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003108 return
3109 }
3110 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003111 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003112 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003113 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3114 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003115 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3116 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003117 return
3118 }
3119 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003121 }
3122 } else {
3123 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 +00003124 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003125 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3126 dh.upgradeCanceled = true
3127 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3128 }
mpagenko1f8e8822021-06-25 14:10:21 +00003129 }
mpagenko15ff4a52021-03-02 10:09:20 +00003130 return
3131 }
mpagenko59862f02021-10-11 08:53:18 +00003132 dh.lockUpgradeFsm.RUnlock()
3133 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3134 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 }
mpagenko59862f02021-10-11 08:53:18 +00003139 return
3140 }
3141 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3142 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3143 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3144 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3145 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3146 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3147 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003148 }
mpagenko15ff4a52021-03-02 10:09:20 +00003149 }
3150 }
3151 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003152 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003153 }
mpagenko59862f02021-10-11 08:53:18 +00003154 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003155}
3156
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303157// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003159
3160 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003161 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003162 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003163 kvbackend := &db.Backend{
3164 Client: dh.pOpenOnuAc.kvClient,
3165 StoreType: dh.pOpenOnuAc.KVStoreType,
3166 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003167 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003168 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3169 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003170
mpagenkoaf801632020-07-03 10:00:42 +00003171 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003172}
khenaidoo7d3c5582021-08-11 18:09:44 -04003173func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303174 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003175
mpagenkodff5dda2020-08-28 11:52:01 +00003176 for _, field := range flow.GetOfbFields(apFlowItem) {
3177 switch field.Type {
3178 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3179 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003181 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3182 }
mpagenko01e726e2020-10-23 09:45:29 +00003183 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003184 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3185 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303186 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003187 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303188 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3189 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003190 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3191 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003192 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003193 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303194 return
mpagenkodff5dda2020-08-28 11:52:01 +00003195 }
3196 }
mpagenko01e726e2020-10-23 09:45:29 +00003197 */
mpagenkodff5dda2020-08-28 11:52:01 +00003198 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3199 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303200 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003201 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303202 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003203 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303204 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003205 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003206 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303207 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003208 }
3209 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3210 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303211 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003212 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303213 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003214 }
3215 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3216 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003217 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003218 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3219 }
3220 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3221 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003223 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3224 }
3225 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_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 "IPv4-DST": field.GetIpv4Dst()})
3229 }
3230 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_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 "IPv4-SRC": field.GetIpv4Src()})
3234 }
3235 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
3239 }
3240 /*
3241 default:
3242 {
3243 //all other entires ignored
3244 }
3245 */
3246 }
3247 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303248}
mpagenkodff5dda2020-08-28 11:52:01 +00003249
khenaidoo7d3c5582021-08-11 18:09:44 -04003250func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003251 for _, action := range flow.GetActions(apFlowItem) {
3252 switch action.Type {
3253 /* not used:
3254 case of.OfpActionType_OFPAT_OUTPUT:
3255 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003256 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003257 "Output": action.GetOutput()})
3258 }
3259 */
3260 case of.OfpActionType_OFPAT_PUSH_VLAN:
3261 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003262 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003263 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3264 }
3265 case of.OfpActionType_OFPAT_SET_FIELD:
3266 {
3267 pActionSetField := action.GetSetField()
3268 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003269 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003270 "OxcmClass": pActionSetField.Field.OxmClass})
3271 }
3272 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303273 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003274 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303275 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003276 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303277 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003278 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303279 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003280 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003281 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003282 "Type": pActionSetField.Field.GetOfbField().Type})
3283 }
3284 }
3285 /*
3286 default:
3287 {
3288 //all other entires ignored
3289 }
3290 */
3291 }
3292 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303293}
3294
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303295// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003296func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003297 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303298 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3299 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303300 var loSetPcp uint8
3301 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303302 var loIPProto uint32
3303 /* the TechProfileId is part of the flow Metadata - compare also comment within
3304 * OLT-Adapter:openolt_flowmgr.go
3305 * Metadata 8 bytes:
3306 * Most Significant 2 Bytes = Inner VLAN
3307 * Next 2 Bytes = Tech Profile ID(TPID)
3308 * Least Significant 4 Bytes = Port ID
3309 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3310 * subscriber related flows.
3311 */
3312
dbainbri4d3a0dc2020-12-02 00:33:42 +00003313 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303314 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003315 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003316 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003317 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303318 }
mpagenko551a4d42020-12-08 18:09:20 +00003319 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003320 loCookie := apFlowItem.GetCookie()
3321 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303322 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303324 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303325
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303326 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003327 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303328 if loIPProto == 2 {
3329 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3330 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003331 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003332 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303333 return nil
3334 }
mpagenko01e726e2020-10-23 09:45:29 +00003335 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003336 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003337
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303338 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3339 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003340 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003342 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3343 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3344 //TODO!!: Use DeviceId within the error response to rwCore
3345 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003346 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003347 }
3348 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003350 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303351 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3352 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3353 loSetVlan = loMatchVlan
3354 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 +00003355 } else {
3356 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3357 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3358 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303359 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003360 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003361 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003362 }
mpagenko9a304ea2020-12-16 15:54:01 +00003363
khenaidoo42dcdfd2021-10-19 17:34:12 -04003364 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003365 if apFlowMetaData != nil {
3366 meter = apFlowMetaData.Meters[0]
3367 }
mpagenkobc4170a2021-08-17 16:42:10 +00003368 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3369 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3370 // when different rules are requested concurrently for the same uni
3371 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3372 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3373 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3375 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003376 //SetUniFlowParams() may block on some rule that is suspended-to-add
3377 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003378 // Also the error is returned to caller via response channel
3379 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303380 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003381 dh.lockVlanConfig.RUnlock()
3382 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003383 return
mpagenkodff5dda2020-08-28 11:52:01 +00003384 }
mpagenkobc4170a2021-08-17 16:42:10 +00003385 dh.lockVlanConfig.RUnlock()
3386 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003387 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303388 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003389 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003390 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003391 if err != nil {
3392 *respChan <- err
3393 }
mpagenko01e726e2020-10-23 09:45:29 +00003394}
3395
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303396// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003397func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003398 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3399 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3400 //no extra check is done on the rule parameters
3401 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3402 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3403 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3404 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003405 // - 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 +00003406 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003408
3409 /* TT related temporary workaround - should not be needed anymore
3410 for _, field := range flow.GetOfbFields(apFlowItem) {
3411 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3412 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003413 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003414 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3415 if loIPProto == 2 {
3416 // 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 +00003417 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003418 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003419 return nil
3420 }
3421 }
3422 } //for all OfbFields
3423 */
3424
mpagenko9a304ea2020-12-16 15:54:01 +00003425 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003426 dh.lockVlanConfig.RLock()
3427 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003428 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3429 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003430 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3431 return
mpagenko01e726e2020-10-23 09:45:29 +00003432 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003433 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003434 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003435 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003436 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003437 // Push response on the response channel
3438 if respChan != nil {
3439 // 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
3440 select {
3441 case *respChan <- nil:
3442 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3443 default:
3444 }
3445 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003447}
3448
Himani Chawla26e555c2020-08-31 12:30:20 +05303449// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003450// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003451// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303453 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Praneeth Kumar Nalmas8f8f0c02024-10-22 19:29:09 +05303454 chVlanFilterFsm := make(chan cmn.Message, 2)
mpagenkodff5dda2020-08-28 11:52:01 +00003455
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003457 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003458 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3459 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003460 }
3461
Sridhar Ravindra2f86efb2024-12-06 11:02:10 +05303462 if dh.pDeviceStateFsm.Current() == devStDown {
3463 logger.Warnw(ctx, "UniVlanConfigFsm : aborting, device state down", log.Fields{"device-id": dh.DeviceID})
3464 return fmt.Errorf("device state down for device-id %x - aborting", dh.DeviceID)
3465 }
3466
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003467 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3468 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303469 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003470 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003471 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3472 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3474 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003475 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3477 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003478 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3479 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003481 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303482 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003483 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3485 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003486 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003487 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003488 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3489 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003490 }
3491 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003492 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493 "device-id": dh.DeviceID})
3494 return fmt.Errorf("uniVlanConfigFsm invalid 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 could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003498 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3499 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003500 }
3501 return nil
3502}
3503
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303504// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003505// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003506func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003507 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003509 for _, uniPort := range dh.uniEntityMap {
3510 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003511 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003512 pCurrentUniPort = uniPort
3513 break //found - end search loop
3514 }
3515 }
3516 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003517 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003519 return
3520 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003521 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003522}
3523
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303524// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003525func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003526 //TODO!! verify and start pending flow configuration
3527 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3528 //but execution was set to 'on hold' as first the TechProfile config had to be applied
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303529 logger.Info(ctx, "Verifying UniVlanConfig Request", log.Fields{"device-id": dh.DeviceID, "UniPort": apUniPort.PortNo, "techprofile-id": aTpID})
mpagenkof1fc3862021-02-16 10:09:52 +00003530 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003532 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003533 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003534 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003535 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003536 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003537 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3539 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003540 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003542 } else {
3543 /***** UniVlanConfigFsm continued */
3544 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003545 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3546 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003547 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3549 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003550 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003551 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003552 } else {
3553 /***** UniVlanConfigFsm continued */
3554 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3556 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003557 }
mpagenkodff5dda2020-08-28 11:52:01 +00003558 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003559 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003560 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3561 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003562 }
3563 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003564 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 +00003565 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3566 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003567 }
3568 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003569 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003571 }
mpagenkof1fc3862021-02-16 10:09:52 +00003572 } else {
3573 dh.lockVlanConfig.RUnlock()
3574 }
mpagenkodff5dda2020-08-28 11:52:01 +00003575}
3576
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303577// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003578// 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 +00003579func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003580 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003581 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003582 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003583 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003585 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003586}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003587
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303588// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003589func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003590 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3591 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3592 // obviously then parallel processing on the cancel must be avoided
3593 // deadline context to ensure completion of background routines waited for
3594 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3595 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3596 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303597 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003598
Akash Soni840f8d62024-12-11 19:37:06 +05303599 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3600 if err != nil {
3601 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3602 return err
3603 }
3604 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003605}
3606
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303607// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3608// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3610 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003612 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303613 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003614 return nil
3615 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003617
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003619 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003620 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3621 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003622 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003623 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003624
mpagenkof1fc3862021-02-16 10:09:52 +00003625 if aWriteToKvStore {
3626 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3627 }
3628 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003629}
3630
dbainbri4d3a0dc2020-12-02 00:33:42 +00003631func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003632 defer cancel() //ensure termination of context (may be pro forma)
3633 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003634 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003636}
3637
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303638// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3639//
3640// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003641func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3642 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3643 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3644 dh.mutexDeviceReason.Lock()
3645 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003646 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003647 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003648 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 DeviceId: dh.DeviceID,
3650 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003651 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003652 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003653 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003654 return err
3655 }
mpagenkoe4782082021-11-25 12:04:26 +00003656 } else {
3657 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 +00003658 }
mpagenkoe4782082021-11-25 12:04:26 +00003659 dh.deviceReason = deviceReason
3660 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3661 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003662 return nil
3663}
3664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3666 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003667 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003668 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3669 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003670 }
mpagenkof1fc3862021-02-16 10:09:52 +00003671 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003672}
3673
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003674// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003675// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003676func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3677 dh.lockDevice.RLock()
3678 defer dh.lockDevice.RUnlock()
3679 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003680 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003681 }
3682 return 0, errors.New("error-fetching-uni-port")
3683}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003684
3685// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003686func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3687 var errorsList []error
3688 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 -08003689
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003690 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3691 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3692 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3693
3694 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3695 // successfully.
3696 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3697 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3698 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 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 -08003700 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003701 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003702 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003703 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003704}
3705
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003706func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3707 var err error
3708 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003709 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003710
3711 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003712 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003713 errorsList = append(errorsList, err)
3714 }
3715 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003716 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003717
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003718 return errorsList
3719}
3720
3721func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3722 var err error
3723 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003724 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003725 // Check if group metric related config is updated
3726 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003727 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3728 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3729 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003730
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 if ok && m.Frequency != v.GroupFreq {
3732 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003733 errorsList = append(errorsList, err)
3734 }
3735 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003736 if ok && m.Enabled != v.Enabled {
3737 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003738 errorsList = append(errorsList, err)
3739 }
3740 }
3741 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003742 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003743 return errorsList
3744}
3745
3746func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3747 var err error
3748 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003749 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003750 // Check if standalone metric related config is updated
3751 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003752 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3753 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3754 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003755
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003756 if ok && m.Frequency != v.SampleFreq {
3757 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003758 errorsList = append(errorsList, err)
3759 }
3760 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003761 if ok && m.Enabled != v.Enabled {
3762 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003763 errorsList = append(errorsList, err)
3764 }
3765 }
3766 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003767 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003768 return errorsList
3769}
3770
3771// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003772func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003773 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003774
3775 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003776 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303777 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003779 // Initialize the next metric collection time.
3780 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3781 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003783 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303784 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3785 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003786 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303787
Girish Gowdrae09a6202021-01-12 18:10:59 -08003788 select {
3789 case <-dh.stopCollector:
3790 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003791 // Stop the L2 PM FSM
3792 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003793 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3794 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3795 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003796 }
3797 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003799 }
3800 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003801 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3802 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003803 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003804 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3805 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003806 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003807
Girish Gowdrae09a6202021-01-12 18:10:59 -08003808 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303809 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003810 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3811 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3812 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3813 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003814 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003815 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
3816 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003817 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003818 } else {
3819 if dh.pmConfigs.Grouped { // metrics are managed as a group
3820 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003822
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003823 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3824 // 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 -08003825 // 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 +00003826 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3827 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003828 }
3829 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3831 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3832 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3833 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003834 }
3835 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003836 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003837
3838 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3840 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3841 // 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 -08003842 // 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 +00003843 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003844 prevInternal := g.NextCollectionInterval
3845 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003846 }
3847 }
3848 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003849 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3850 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3851 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003852 prevInternal := m.NextCollectionInterval
3853 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003854 }
3855 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003856 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003857 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003858 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003859 } */
3860 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003861 }
3862 }
3863}
kesavandfdf77632021-01-26 23:40:33 -05003864
Akash Soni3c176c62024-12-04 13:30:43 +05303865func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
3866
3867 singleValResp := extension.SingleSetValueResponse{
3868 Response: &extension.SetValueResponse{
3869 Status: extension.SetValueResponse_OK,
3870 },
3871 }
3872
3873 return &singleValResp
3874}
3875
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003876func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003877
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003878 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3879 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003880}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003881
Himani Chawla43f95ff2021-06-03 00:24:12 +05303882func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3883 if dh.pOnuMetricsMgr == nil {
3884 return &extension.SingleGetValueResponse{
3885 Response: &extension.GetValueResponse{
3886 Status: extension.GetValueResponse_ERROR,
3887 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3888 },
3889 }
3890 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303891 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303892 return resp
3893}
3894
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003895func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3896
3897 var err error
3898 var pDevOmciCC *cmn.OmciCC
3899 if dh.pOnuOmciDevice == nil {
3900 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3901 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3902 } else {
3903 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3904 if pDevOmciCC == nil {
3905 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3906 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3907 }
3908 }
3909 if err != nil {
3910 return &extension.SingleGetValueResponse{
3911 Response: &extension.GetValueResponse{
3912 Status: extension.GetValueResponse_ERROR,
3913 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3914 },
3915 },
3916 err
3917 }
3918 return pDevOmciCC.GetOmciCounters(), nil
3919}
3920
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003921func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3922 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003923 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003924 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003926}
3927
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003929 var pAdapterFsm *cmn.AdapterFsm
3930 //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 +00003931 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003933 {
mpagenkofbf577d2021-10-12 11:44:33 +00003934 if dh.pOnuOmciDevice != nil {
3935 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3936 } else {
3937 return true //FSM not active - so there is no activity on omci
3938 }
mpagenkof1fc3862021-02-16 10:09:52 +00003939 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003940 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003941 {
mpagenkofbf577d2021-10-12 11:44:33 +00003942 if dh.pOnuOmciDevice != nil {
3943 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3944 } else {
3945 return true //FSM not active - so there is no activity on omci
3946 }
mpagenkof1fc3862021-02-16 10:09:52 +00003947 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003948 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003949 {
mpagenkofbf577d2021-10-12 11:44:33 +00003950 if dh.pLockStateFsm != nil {
3951 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3952 } else {
3953 return true //FSM not active - so there is no activity on omci
3954 }
mpagenkof1fc3862021-02-16 10:09:52 +00003955 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003957 {
mpagenkofbf577d2021-10-12 11:44:33 +00003958 if dh.pUnlockStateFsm != nil {
3959 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3960 } else {
3961 return true //FSM not active - so there is no activity on omci
3962 }
mpagenkof1fc3862021-02-16 10:09:52 +00003963 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003964 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003965 {
mpagenkofbf577d2021-10-12 11:44:33 +00003966 if dh.pOnuMetricsMgr != nil {
3967 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003968 } else {
3969 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003970 }
3971 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003972 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003973 {
3974 dh.lockUpgradeFsm.RLock()
3975 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003976 if dh.pOnuUpradeFsm != nil {
3977 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3978 } else {
3979 return true //FSM not active - so there is no activity on omci
3980 }
mpagenko80622a52021-02-09 16:53:23 +00003981 }
mpagenkof1fc3862021-02-16 10:09:52 +00003982 default:
3983 {
3984 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003985 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003986 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003987 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003988 }
mpagenkofbf577d2021-10-12 11:44:33 +00003989 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3990 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3991 }
3992 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003993}
3994
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3996 for _, v := range dh.pOnuTP.PAniConfigFsm {
3997 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003998 return false
3999 }
4000 }
4001 return true
4002}
4003
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004004func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004005 dh.lockVlanConfig.RLock()
4006 defer dh.lockVlanConfig.RUnlock()
4007 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004008 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004009 return false
4010 }
4011 }
4012 return true //FSM not active - so there is no activity on omci
4013}
4014
4015func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4016 dh.lockVlanConfig.RLock()
4017 defer dh.lockVlanConfig.RUnlock()
4018 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004019 if v.PAdaptFsm.PFsm != nil {
4020 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004021 return true //there is at least one VLAN FSM with some active configuration
4022 }
4023 }
4024 }
4025 return false //there is no VLAN FSM with some active configuration
4026}
4027
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004028func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004029 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4030 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4031 return false
4032 }
4033 }
4034 // a further check is done to identify, if at least some data traffic related configuration exists
4035 // 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])
4036 return dh.checkUserServiceExists(ctx)
4037}
4038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004039func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304040 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 +00004041 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004042 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004043 // TODO: fatal error reset ONU, delete deviceHandler!
4044 return
4045 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4047 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004048}
4049
4050func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4051 dh.mutexCollectorFlag.Lock()
4052 dh.collectorIsRunning = flagValue
4053 dh.mutexCollectorFlag.Unlock()
4054}
4055
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004056func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004057 dh.mutexCollectorFlag.RLock()
4058 flagValue := dh.collectorIsRunning
4059 dh.mutexCollectorFlag.RUnlock()
4060 return flagValue
4061}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304062
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304063func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4064 dh.mutextAlarmManagerFlag.Lock()
4065 dh.alarmManagerIsRunning = flagValue
4066 dh.mutextAlarmManagerFlag.Unlock()
4067}
4068
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004069func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304070 dh.mutextAlarmManagerFlag.RLock()
4071 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004072 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304073 dh.mutextAlarmManagerFlag.RUnlock()
4074 return flagValue
4075}
4076
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004077func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004078 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304079
4080 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004081 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304082 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304083 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304084 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304085 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004086 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4087 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304088 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304089 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004090 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4091 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304092 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304093 }
4094}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004095
Girish Gowdrae95687a2021-09-08 16:30:58 -07004096func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4097 dh.mutexFlowMonitoringRoutineFlag.Lock()
4098 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004099 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004100 dh.isFlowMonitoringRoutineActive[uniID] = flag
4101}
4102
4103func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4104 dh.mutexFlowMonitoringRoutineFlag.RLock()
4105 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4106 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004107 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304108 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4109 return dh.isFlowMonitoringRoutineActive[uniID]
4110 }
4111 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004112}
4113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004114func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304115 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004116
Maninder7961d722021-06-16 22:10:28 +05304117 connectStatus := voltha.ConnectStatus_UNREACHABLE
4118 operState := voltha.OperStatus_UNKNOWN
4119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004120 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004121 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004122 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004123 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004124 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004125 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304126 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004127 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4128 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4129 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4130 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4131 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4132 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4133 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4134 // However, a later refactoring of the functionality remains unaffected.
4135 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004136 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004137 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304138 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004139 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304140 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004141 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004142 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304143 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004144 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4145 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304146 operState = voltha.OperStatus_ACTIVE
4147 } else {
4148 operState = voltha.OperStatus_ACTIVATING
4149 }
4150 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004151 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4152 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4153 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304154 operState = voltha.OperStatus_DISCOVERED
4155 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004156 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004157 logger.Debugw(ctx, "Core DeviceStateUpdate",
4158 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304159 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304160 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004161 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004162 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004163 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004164 ConnStatus: connectStatus,
4165 OperStatus: operState,
4166 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304167 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004168 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304169 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004170 } else {
Maninderb5187552021-03-23 22:23:42 +05304171 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004172 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304173
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004174 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304175 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004176 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004177 } else {
4178 onuDevEntry.MutexPersOnuConfig.RLock()
4179 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4180 connectStatus = voltha.ConnectStatus_REACHABLE
4181 }
4182 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304183 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004184 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004185 }
mpagenko101ac942021-11-16 15:01:29 +00004186 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004187 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004188 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004189 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304190
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304192 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004193 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004194 } else {
4195 onuDevEntry.MutexPersOnuConfig.RLock()
4196 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4197 connectStatus = voltha.ConnectStatus_REACHABLE
4198 }
4199 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304200 }
4201
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004202 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304203
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004204 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004205 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004206 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004207 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004208 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004209
4210 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4211 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4212 } else {
4213 onuDevEntry.MutexReconciledTpInstances.Lock()
4214 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4215 onuDevEntry.MutexReconciledTpInstances.Unlock()
4216 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004217 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004218 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004219 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304220 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004221 dh.reconciling = cSkipOnuConfigReconciling
4222 } else {
4223 dh.reconciling = cOnuConfigReconciling
4224 }
4225 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004226}
4227
mpagenko101ac942021-11-16 15:01:29 +00004228func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304229 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004230 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004231 dh.sendChReconcileFinished(success)
4232 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4233 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4234 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004235 } else {
mpagenko101ac942021-11-16 15:01:29 +00004236 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004237 }
4238}
4239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004240func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004241 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004242 defer dh.mutexReconcilingFlag.RUnlock()
4243 return dh.reconciling != cNoReconciling
4244}
4245
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004246func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004247 dh.mutexReconcilingFlag.RLock()
4248 defer dh.mutexReconcilingFlag.RUnlock()
4249 return dh.reconciling == cSkipOnuConfigReconciling
4250}
4251
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004252func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4253 dh.mutexReconcilingFirstPassFlag.Lock()
4254 dh.reconcilingFirstPass = value
4255 dh.mutexReconcilingFirstPassFlag.Unlock()
4256}
4257
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004258func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4259 dh.mutexReconcilingReasonUpdate.Lock()
4260 dh.reconcilingReasonUpdate = value
4261 dh.mutexReconcilingReasonUpdate.Unlock()
4262}
4263
4264func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4265 dh.mutexReconcilingReasonUpdate.RLock()
4266 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4267 return dh.reconcilingReasonUpdate
4268}
4269
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004270func (dh *deviceHandler) getDeviceReason() uint8 {
4271 dh.mutexDeviceReason.RLock()
4272 value := dh.deviceReason
4273 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004274 return value
4275}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004276
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004277func (dh *deviceHandler) GetDeviceReasonString() string {
4278 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004279}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004280
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004281func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004282 dh.mutexReadyForOmciConfig.Lock()
4283 dh.readyForOmciConfig = flagValue
4284 dh.mutexReadyForOmciConfig.Unlock()
4285}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004286func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004287 dh.mutexReadyForOmciConfig.RLock()
4288 flagValue := dh.readyForOmciConfig
4289 dh.mutexReadyForOmciConfig.RUnlock()
4290 return flagValue
4291}
Maninder7961d722021-06-16 22:10:28 +05304292
4293func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004294 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304295 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004296 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304297 }
4298
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004299 logger.Debugw(ctx, "Core DeviceStateUpdate",
4300 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004301 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004302 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004303 ConnStatus: connectStatus,
4304 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4305 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304306 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004307 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304308 }
4309}
khenaidoo7d3c5582021-08-11 18:09:44 -04004310
4311/*
4312Helper functions to communicate with Core
4313*/
4314
4315func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4316 cClient, err := dh.coreClient.GetCoreServiceClient()
4317 if err != nil || cClient == nil {
4318 return nil, err
4319 }
4320 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4321 defer cancel()
4322 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4323 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4324}
4325
khenaidoo42dcdfd2021-10-19 17:34:12 -04004326func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004327 cClient, err := dh.coreClient.GetCoreServiceClient()
4328 if err != nil || cClient == nil {
4329 return err
4330 }
4331 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4332 defer cancel()
4333 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004334 logger.Debugw(subCtx, "device-updated-in-core",
4335 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004336 return err
4337}
4338
4339func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4340 cClient, err := dh.coreClient.GetCoreServiceClient()
4341 if err != nil || cClient == nil {
4342 return err
4343 }
4344 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4345 defer cancel()
4346 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004347 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4348 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004349 return err
4350}
4351
4352func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4353 cClient, err := dh.coreClient.GetCoreServiceClient()
4354 if err != nil || cClient == nil {
4355 return err
4356 }
4357 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4358 defer cancel()
4359 _, err = cClient.DeviceUpdate(subCtx, device)
4360 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4361 return err
4362}
4363
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004364func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004365 cClient, err := dh.coreClient.GetCoreServiceClient()
4366 if err != nil || cClient == nil {
4367 return err
4368 }
4369 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4370 defer cancel()
4371 _, err = cClient.PortCreated(subCtx, port)
4372 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4373 return err
4374}
4375
khenaidoo42dcdfd2021-10-19 17:34:12 -04004376func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004377 cClient, err := dh.coreClient.GetCoreServiceClient()
4378 if err != nil || cClient == nil {
4379 return err
4380 }
4381 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4382 defer cancel()
4383 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004384 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 -04004385 return err
4386}
4387
khenaidoo42dcdfd2021-10-19 17:34:12 -04004388func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004389 cClient, err := dh.coreClient.GetCoreServiceClient()
4390 if err != nil || cClient == nil {
4391 return err
4392 }
4393 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4394 defer cancel()
4395 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004396 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 -04004397 return err
4398}
4399
4400/*
4401Helper functions to communicate with parent adapter
4402*/
4403
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004404func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4405 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4406
4407 var request = ia.TechProfileInstanceRequestMessage{
4408 DeviceId: dh.DeviceID,
4409 TpInstancePath: aTpPath,
4410 ParentDeviceId: dh.parentID,
4411 ParentPonPort: dh.device.ParentPortNo,
4412 OnuId: dh.device.ProxyAddress.OnuId,
4413 UniId: uint32(aUniID),
4414 }
4415
4416 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004417 if err != nil || pgClient == nil {
4418 return nil, err
4419 }
4420 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4421 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004422 logger.Debugw(subCtx, "get-tech-profile-instance",
4423 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004424 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004425}
4426
Girish Gowdrae95687a2021-09-08 16:30:58 -07004427// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4428// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4429func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4430 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4431 dh.setFlowMonitoringIsRunning(uniID, true)
4432 for {
4433 select {
4434 // block on the channel to receive an incoming flow
4435 // process the flow completely before proceeding to handle the next flow
4436 case flowCb := <-dh.flowCbChan[uniID]:
4437 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304438 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004439 respChan := make(chan error)
4440 if flowCb.addFlow {
4441 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4442 } else {
4443 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4444 }
4445 // Block on response and tunnel it back to the caller
4446 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304447 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004448 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4449 case <-dh.stopFlowMonitoringRoutine[uniID]:
4450 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4451 dh.setFlowMonitoringIsRunning(uniID, false)
4452 return
4453 }
4454 }
4455}
4456
kesavand011d5162021-11-25 19:21:06 +05304457func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4458 request.ParentDeviceId = dh.GetProxyAddressID()
4459 request.ChildDeviceId = dh.DeviceID
4460 request.ProxyAddress = dh.GetProxyAddress()
4461 request.ConnectStatus = common.ConnectStatus_REACHABLE
4462
4463 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4464 if err != nil || pgClient == nil {
4465 return err
4466 }
4467 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4468 defer cancel()
4469 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4470 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4471 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004472 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4473 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304474 }
4475 return err
4476}
4477
khenaidoo42dcdfd2021-10-19 17:34:12 -04004478func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004479 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4480 if err != nil || pgClient == nil {
4481 return err
4482 }
4483 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4484 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004485 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004486 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004487 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4488 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004489 if status.Code(err) == codes.Unavailable {
4490 dh.setOltAvailable(false)
4491 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004492 logger.Errorw(ctx, "omci-failure",
4493 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004494 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004495 }
4496 return err
4497}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004498
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004499func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4500 // Check if there are additional TCONT instances necessary/available
4501 pDevEntry.MutexPersOnuConfig.Lock()
4502 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4503 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4504 pDevEntry.MutexPersOnuConfig.Unlock()
4505 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4506 logger.Debugw(ctx, "checking available TCONT instances",
4507 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4508 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4509 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4510 log.Fields{"device-id": dh.device.Id})
4511 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4512 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4513 }
4514 } else {
4515 pDevEntry.MutexPersOnuConfig.Unlock()
4516 }
4517 // Check if there are enough PrioQueue instances available
4518 if dh.pOnuTP != nil {
4519 var numberOfUsPrioQueueDbInsts int
4520
4521 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4522 for _, mgmtEntityID := range queueInstKeys {
4523 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4524 numberOfUsPrioQueueDbInsts++
4525 }
4526 }
4527 // Check if there is an upstream PriorityQueue instance available for each Gem port
4528 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4529 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4530 log.Fields{"device-id": dh.DeviceID,
4531 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4532 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4533 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4534
4535 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4536 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4537 log.Fields{"device-id": dh.device.Id})
4538 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4539 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4540 }
4541 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4542 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4543 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4544 } else {
4545 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4546 log.Fields{"device-id": dh.DeviceID})
4547 }
4548 return nil
4549}
4550
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004551// GetDeviceID - TODO: add comment
4552func (dh *deviceHandler) GetDeviceID() string {
4553 return dh.DeviceID
4554}
4555
4556// GetProxyAddressID - TODO: add comment
4557func (dh *deviceHandler) GetProxyAddressID() string {
4558 return dh.device.ProxyAddress.GetDeviceId()
4559}
4560
4561// GetProxyAddressType - TODO: add comment
4562func (dh *deviceHandler) GetProxyAddressType() string {
4563 return dh.device.ProxyAddress.GetDeviceType()
4564}
4565
4566// GetProxyAddress - TODO: add comment
4567func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4568 return dh.device.ProxyAddress
4569}
4570
4571// GetEventProxy - TODO: add comment
4572func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4573 return dh.EventProxy
4574}
4575
4576// GetOmciTimeout - TODO: add comment
4577func (dh *deviceHandler) GetOmciTimeout() int {
4578 return dh.pOpenOnuAc.omciTimeout
4579}
4580
4581// GetAlarmAuditInterval - TODO: add comment
4582func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4583 return dh.pOpenOnuAc.alarmAuditInterval
4584}
4585
4586// GetDlToOnuTimeout4M - TODO: add comment
4587func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4588 return dh.pOpenOnuAc.dlToOnuTimeout4M
4589}
4590
4591// GetUniEntityMap - TODO: add comment
4592func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4593 return &dh.uniEntityMap
4594}
4595
4596// GetPonPortNumber - TODO: add comment
4597func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4598 return &dh.ponPortNumber
4599}
4600
4601// GetUniVlanConfigFsm - TODO: add comment
4602func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004603 dh.lockVlanConfig.RLock()
4604 value := dh.UniVlanConfigFsmMap[uniID]
4605 dh.lockVlanConfig.RUnlock()
4606 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004607}
4608
4609// GetOnuAlarmManager - TODO: add comment
4610func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4611 return dh.pAlarmMgr
4612}
4613
4614// GetOnuMetricsManager - TODO: add comment
4615func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4616 return dh.pOnuMetricsMgr
4617}
4618
4619// GetOnuTP - TODO: add comment
4620func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4621 return dh.pOnuTP
4622}
4623
4624// GetBackendPathPrefix - TODO: add comment
4625func (dh *deviceHandler) GetBackendPathPrefix() string {
4626 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4627}
4628
4629// GetOnuIndication - TODO: add comment
4630func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4631 return dh.pOnuIndication
4632}
4633
4634// RLockMutexDeletionInProgressFlag - TODO: add comment
4635func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4636 dh.mutexDeletionInProgressFlag.RLock()
4637}
4638
4639// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4640func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4641 dh.mutexDeletionInProgressFlag.RUnlock()
4642}
4643
4644// GetDeletionInProgress - TODO: add comment
4645func (dh *deviceHandler) GetDeletionInProgress() bool {
4646 return dh.deletionInProgress
4647}
4648
4649// GetPmConfigs - TODO: add comment
4650func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4651 return dh.pmConfigs
4652}
4653
4654// GetDeviceType - TODO: add comment
4655func (dh *deviceHandler) GetDeviceType() string {
4656 return dh.DeviceType
4657}
4658
4659// GetLogicalDeviceID - TODO: add comment
4660func (dh *deviceHandler) GetLogicalDeviceID() string {
4661 return dh.logicalDeviceID
4662}
4663
4664// GetDevice - TODO: add comment
4665func (dh *deviceHandler) GetDevice() *voltha.Device {
4666 return dh.device
4667}
4668
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004669func (dh *deviceHandler) setOltAvailable(value bool) {
4670 dh.mutexOltAvailable.Lock()
4671 dh.oltAvailable = value
4672 dh.mutexOltAvailable.Unlock()
4673}
4674
4675// IsOltAvailable - TODO: add comment
4676func (dh *deviceHandler) IsOltAvailable() bool {
4677 dh.mutexOltAvailable.RLock()
4678 defer dh.mutexOltAvailable.RUnlock()
4679 return dh.oltAvailable
4680}
4681
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004682// GetMetricsEnabled - TODO: add comment
4683func (dh *deviceHandler) GetMetricsEnabled() bool {
4684 return dh.pOpenOnuAc.MetricsEnabled
4685}
4686
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004687// GetExtendedOmciSupportEnabled - TODO: add comment
4688func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4689 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4690}
4691
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304692// GetExtendedOmciSupportEnabled - TODO: add comment
4693func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
4694 return dh.pOpenOnuAc.skipOnuConfig
4695}
4696
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004697// InitPmConfigs - TODO: add comment
4698func (dh *deviceHandler) InitPmConfigs() {
4699 dh.pmConfigs = &voltha.PmConfigs{}
4700}
4701
4702// GetUniPortMask - TODO: add comment
4703func (dh *deviceHandler) GetUniPortMask() int {
4704 return dh.pOpenOnuAc.config.UniPortMask
4705}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004706
4707func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4708 tpPathFound := false
4709 for _, tpPath := range aTpPathMap {
4710 if tpPath != "" {
4711 tpPathFound = true
4712 }
4713 }
4714 return tpPathFound
4715}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004716
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304717func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4718 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4719 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4720 return resp
4721}
4722
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05304723func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
4724 return dh.deviceDeleteCommChan
4725}
4726
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004727// PrepareForGarbageCollection - remove references to prepare for garbage collection
4728func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4729 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4730
4731 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4732 // first let the objects rest for some time to give all asynchronously started
4733 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004734 time.Sleep(2 * time.Second)
4735
4736 if dh.pOnuOmciDevice != nil {
4737 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4738 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4739 // reset handling (even in future coding), request monitoring is canceled here one last time to
4740 // be sure that all corresponding go routines are terminated
4741 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4742 }
4743 }
4744 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004745
4746 if dh.pOnuTP != nil {
4747 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4748 }
4749 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004750 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4751 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004752 select {
4753 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4754 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4755 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4756 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004757 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004758 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004759 }
4760 if dh.pAlarmMgr != nil {
4761 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4762 }
4763 if dh.pSelfTestHdlr != nil {
4764 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4765 }
4766 if dh.pLockStateFsm != nil {
4767 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4768 }
4769 if dh.pUnlockStateFsm != nil {
4770 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4771 }
4772 if dh.pOnuUpradeFsm != nil {
4773 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4774 }
4775 if dh.pOnuOmciDevice != nil {
4776 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4777 }
4778 for k, v := range dh.UniVlanConfigFsmMap {
4779 v.PrepareForGarbageCollection(ctx, aDeviceID)
4780 delete(dh.UniVlanConfigFsmMap, k)
4781 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05304782 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004783 dh.pOnuOmciDevice = nil
4784 dh.pOnuTP = nil
4785 dh.pOnuMetricsMgr = nil
4786 dh.pAlarmMgr = nil
4787 dh.pSelfTestHdlr = nil
4788 dh.pLockStateFsm = nil
4789 dh.pUnlockStateFsm = nil
4790 dh.pOnuUpradeFsm = nil
4791}