blob: 8daca7682fec5d778fd1e105397e11bbcb53aafb [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
Akash Soni3de0e062024-12-11 16:37:26 +05303577// handleAniConfigFSMFailure handles the failure of the ANI config FSM by resetting the VLAN filter FSM
3578func (dh *deviceHandler) HandleAniConfigFSMFailure(ctx context.Context, uniID uint8) {
3579 dh.lockVlanConfig.Lock()
3580 defer dh.lockVlanConfig.Unlock()
3581
3582 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniID]; exist {
3583 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
3584 if pVlanFilterStatemachine != nil {
3585 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvReset); err != nil {
3586 logger.Warnw(ctx, "Failed to reset UniVlanConfigFsm", log.Fields{
3587 "err": err, "device-id": dh.DeviceID, "UniPort": uniID, "FsmState": pVlanFilterStatemachine.Current(),
3588 })
3589 } else {
3590 logger.Infow(ctx, "Successfully reset UniVlanConfigFsm", log.Fields{
3591 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID, "UniPort": uniID,
3592 })
3593 }
3594 } else {
3595 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no reset performed", log.Fields{
3596 "device-id": dh.DeviceID, "UniPort": uniID,
3597 })
3598 }
3599 } else {
3600 logger.Debugw(ctx, "No UniVlanConfigFsm found for the UNI ID", log.Fields{
3601 "device-id": dh.DeviceID, "UniPort": uniID,
3602 })
3603 }
3604}
3605
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303606// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003607// 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 +00003608func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003609 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003610 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003611 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003612 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003613 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003614 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003615}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003616
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303617// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003619 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3620 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3621 // obviously then parallel processing on the cancel must be avoided
3622 // deadline context to ensure completion of background routines waited for
3623 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3624 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3625 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Akash Soni840f8d62024-12-11 19:37:06 +05303626 defer cancel() // Ensure cancel is called to release resources
mpagenkof1fc3862021-02-16 10:09:52 +00003627
Akash Soni840f8d62024-12-11 19:37:06 +05303628 err := aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx))
3629 if err != nil {
3630 logger.Errorw(ctx, "UpdateOnuKvStore-failed", log.Fields{"device-id": dh.DeviceID})
3631 return err
3632 }
3633 return nil
mpagenkof1fc3862021-02-16 10:09:52 +00003634}
3635
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303636// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3637// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003638func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3639 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003640
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 if dh.IsReconciling() {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05303642 logger.Info(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003643 return nil
3644 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003645 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003646
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003647 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003648 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3650 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003651 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003652 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003653
mpagenkof1fc3862021-02-16 10:09:52 +00003654 if aWriteToKvStore {
3655 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3656 }
3657 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003658}
3659
dbainbri4d3a0dc2020-12-02 00:33:42 +00003660func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003661 defer cancel() //ensure termination of context (may be pro forma)
3662 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003663 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003664 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003665}
3666
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303667// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3668//
3669// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003670func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3671 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3672 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3673 dh.mutexDeviceReason.Lock()
3674 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003675 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003676 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003677 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003678 DeviceId: dh.DeviceID,
3679 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003680 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003681 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003682 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003683 return err
3684 }
mpagenkoe4782082021-11-25 12:04:26 +00003685 } else {
3686 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 +00003687 }
mpagenkoe4782082021-11-25 12:04:26 +00003688 dh.deviceReason = deviceReason
3689 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3690 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003691 return nil
3692}
3693
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3695 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003696 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003697 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3698 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003699 }
mpagenkof1fc3862021-02-16 10:09:52 +00003700 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003701}
3702
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003703// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003704// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003705func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3706 dh.lockDevice.RLock()
3707 defer dh.lockDevice.RUnlock()
3708 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003710 }
3711 return 0, errors.New("error-fetching-uni-port")
3712}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003713
3714// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003715func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3716 var errorsList []error
3717 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 -08003718
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003719 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3720 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3721 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3722
3723 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3724 // successfully.
3725 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3726 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3727 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003728 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 -08003729 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003730 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003732 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003733}
3734
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003735func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3736 var err error
3737 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003738 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003739
3740 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003741 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003742 errorsList = append(errorsList, err)
3743 }
3744 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003745 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003746
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003747 return errorsList
3748}
3749
3750func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3751 var err error
3752 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003753 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003754 // Check if group metric related config is updated
3755 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003756 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3757 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3758 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003759
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760 if ok && m.Frequency != v.GroupFreq {
3761 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003762 errorsList = append(errorsList, err)
3763 }
3764 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765 if ok && m.Enabled != v.Enabled {
3766 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003767 errorsList = append(errorsList, err)
3768 }
3769 }
3770 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003771 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003772 return errorsList
3773}
3774
3775func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3776 var err error
3777 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003778 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003779 // Check if standalone metric related config is updated
3780 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003781 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3782 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3783 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003784
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003785 if ok && m.Frequency != v.SampleFreq {
3786 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003787 errorsList = append(errorsList, err)
3788 }
3789 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003790 if ok && m.Enabled != v.Enabled {
3791 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003792 errorsList = append(errorsList, err)
3793 }
3794 }
3795 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003796 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003797 return errorsList
3798}
3799
3800// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003801func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003802 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003803
3804 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003805 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303806 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003807 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003808 // Initialize the next metric collection time.
3809 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3810 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003811 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003812 dh.setCollectorIsRunning(true)
praneeth nalmas808f43a2023-05-14 12:54:34 +05303813 statsCollectionticker := time.NewTicker((pmmgr.FrequencyGranularity) * time.Second)
3814 defer statsCollectionticker.Stop()
Girish Gowdrae09a6202021-01-12 18:10:59 -08003815 for {
praneeth nalmas808f43a2023-05-14 12:54:34 +05303816
Girish Gowdrae09a6202021-01-12 18:10:59 -08003817 select {
3818 case <-dh.stopCollector:
3819 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003820 // Stop the L2 PM FSM
3821 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003822 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3823 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3824 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003825 }
3826 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003828 }
3829 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3831 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003832 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003833 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3834 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003835 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003836
Girish Gowdrae09a6202021-01-12 18:10:59 -08003837 return
praneeth nalmas808f43a2023-05-14 12:54:34 +05303838 case <-statsCollectionticker.C: // Check every FrequencyGranularity to see if it is time for collecting metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003839 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3840 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3841 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3842 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003843 // Update the next metric collection time.
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003844 prevInternal := dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime
3845 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = prevInternal.Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003846 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003847 } else {
3848 if dh.pmConfigs.Grouped { // metrics are managed as a group
3849 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003850 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003851
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003852 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3853 // 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 -08003854 // 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 +00003855 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3856 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003857 }
3858 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003859 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3860 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3861 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3862 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003863 }
3864 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003865 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003866
3867 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3869 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3870 // 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 -08003871 // 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 +00003872 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003873 prevInternal := g.NextCollectionInterval
3874 g.NextCollectionInterval = prevInternal.Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003875 }
3876 }
3877 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003878 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3879 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3880 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
Mahir Gunyele184e9f2024-09-18 00:12:19 -07003881 prevInternal := m.NextCollectionInterval
3882 m.NextCollectionInterval = prevInternal.Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003883 }
3884 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003886 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003887 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003888 } */
3889 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003890 }
3891 }
3892}
kesavandfdf77632021-01-26 23:40:33 -05003893
Akash Soni3c176c62024-12-04 13:30:43 +05303894func (dh *deviceHandler) setOnuOffloadStats(ctx context.Context, config *extension.AppOffloadOnuConfig) *extension.SingleSetValueResponse {
3895
3896 singleValResp := extension.SingleSetValueResponse{
3897 Response: &extension.SetValueResponse{
3898 Status: extension.SetValueResponse_OK,
3899 },
3900 }
3901
3902 return &singleValResp
3903}
3904
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003907 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3908 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003909}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003910
Himani Chawla43f95ff2021-06-03 00:24:12 +05303911func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3912 if dh.pOnuMetricsMgr == nil {
3913 return &extension.SingleGetValueResponse{
3914 Response: &extension.GetValueResponse{
3915 Status: extension.GetValueResponse_ERROR,
3916 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3917 },
3918 }
3919 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303920 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303921 return resp
3922}
3923
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003924func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3925
3926 var err error
3927 var pDevOmciCC *cmn.OmciCC
3928 if dh.pOnuOmciDevice == nil {
3929 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3930 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3931 } else {
3932 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3933 if pDevOmciCC == nil {
3934 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3935 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3936 }
3937 }
3938 if err != nil {
3939 return &extension.SingleGetValueResponse{
3940 Response: &extension.GetValueResponse{
3941 Status: extension.GetValueResponse_ERROR,
3942 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3943 },
3944 },
3945 err
3946 }
3947 return pDevOmciCC.GetOmciCounters(), nil
3948}
3949
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003950func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3951 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003952 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003953 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003954 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003955}
3956
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003957func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003958 var pAdapterFsm *cmn.AdapterFsm
3959 //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 +00003960 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003961 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003962 {
mpagenkofbf577d2021-10-12 11:44:33 +00003963 if dh.pOnuOmciDevice != nil {
3964 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3965 } else {
3966 return true //FSM not active - so there is no activity on omci
3967 }
mpagenkof1fc3862021-02-16 10:09:52 +00003968 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003969 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003970 {
mpagenkofbf577d2021-10-12 11:44:33 +00003971 if dh.pOnuOmciDevice != nil {
3972 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3973 } else {
3974 return true //FSM not active - so there is no activity on omci
3975 }
mpagenkof1fc3862021-02-16 10:09:52 +00003976 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003977 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003978 {
mpagenkofbf577d2021-10-12 11:44:33 +00003979 if dh.pLockStateFsm != nil {
3980 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3981 } else {
3982 return true //FSM not active - so there is no activity on omci
3983 }
mpagenkof1fc3862021-02-16 10:09:52 +00003984 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003985 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003986 {
mpagenkofbf577d2021-10-12 11:44:33 +00003987 if dh.pUnlockStateFsm != nil {
3988 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3989 } else {
3990 return true //FSM not active - so there is no activity on omci
3991 }
mpagenkof1fc3862021-02-16 10:09:52 +00003992 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003994 {
mpagenkofbf577d2021-10-12 11:44:33 +00003995 if dh.pOnuMetricsMgr != nil {
3996 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003997 } else {
3998 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003999 }
4000 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004001 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00004002 {
4003 dh.lockUpgradeFsm.RLock()
4004 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00004005 if dh.pOnuUpradeFsm != nil {
4006 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
4007 } else {
4008 return true //FSM not active - so there is no activity on omci
4009 }
mpagenko80622a52021-02-09 16:53:23 +00004010 }
mpagenkof1fc3862021-02-16 10:09:52 +00004011 default:
4012 {
4013 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004014 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00004015 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004016 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004017 }
mpagenkofbf577d2021-10-12 11:44:33 +00004018 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
4019 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
4020 }
4021 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004022}
4023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
4025 for _, v := range dh.pOnuTP.PAniConfigFsm {
4026 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004027 return false
4028 }
4029 }
4030 return true
4031}
4032
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004033func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004034 dh.lockVlanConfig.RLock()
4035 defer dh.lockVlanConfig.RUnlock()
4036 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004038 return false
4039 }
4040 }
4041 return true //FSM not active - so there is no activity on omci
4042}
4043
4044func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
4045 dh.lockVlanConfig.RLock()
4046 defer dh.lockVlanConfig.RUnlock()
4047 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 if v.PAdaptFsm.PFsm != nil {
4049 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00004050 return true //there is at least one VLAN FSM with some active configuration
4051 }
4052 }
4053 }
4054 return false //there is no VLAN FSM with some active configuration
4055}
4056
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004057func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00004058 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
4059 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
4060 return false
4061 }
4062 }
4063 // a further check is done to identify, if at least some data traffic related configuration exists
4064 // 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])
4065 return dh.checkUserServiceExists(ctx)
4066}
4067
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004068func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304069 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 +00004070 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004072 // TODO: fatal error reset ONU, delete deviceHandler!
4073 return
4074 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004075 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4076 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004077}
4078
4079func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4080 dh.mutexCollectorFlag.Lock()
4081 dh.collectorIsRunning = flagValue
4082 dh.mutexCollectorFlag.Unlock()
4083}
4084
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004085func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004086 dh.mutexCollectorFlag.RLock()
4087 flagValue := dh.collectorIsRunning
4088 dh.mutexCollectorFlag.RUnlock()
4089 return flagValue
4090}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304091
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304092func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4093 dh.mutextAlarmManagerFlag.Lock()
4094 dh.alarmManagerIsRunning = flagValue
4095 dh.mutextAlarmManagerFlag.Unlock()
4096}
4097
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004098func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304099 dh.mutextAlarmManagerFlag.RLock()
4100 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004101 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304102 dh.mutextAlarmManagerFlag.RUnlock()
4103 return flagValue
4104}
4105
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004106func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004107 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304108
4109 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004110 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304111 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304112 if stop := <-dh.stopAlarmManager; stop {
Sridhar Ravindraf1331ad2024-02-15 16:13:37 +05304113 logger.Debugw(ctx, "stopping-alarm-manager-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawlad3dac422021-03-13 02:31:31 +05304114 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004115 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4116 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304117 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304118 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004119 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4120 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304121 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304122 }
4123}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004124
Girish Gowdrae95687a2021-09-08 16:30:58 -07004125func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4126 dh.mutexFlowMonitoringRoutineFlag.Lock()
4127 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004128 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004129 dh.isFlowMonitoringRoutineActive[uniID] = flag
4130}
4131
4132func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4133 dh.mutexFlowMonitoringRoutineFlag.RLock()
4134 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4135 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004136 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Sridhar Ravindrae9a8bcc2024-12-06 10:40:54 +05304137 if len(dh.isFlowMonitoringRoutineActive) != 0 {
4138 return dh.isFlowMonitoringRoutineActive[uniID]
4139 }
4140 return false
Girish Gowdrae95687a2021-09-08 16:30:58 -07004141}
4142
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004143func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304144 logger.Info(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004145
Maninder7961d722021-06-16 22:10:28 +05304146 connectStatus := voltha.ConnectStatus_UNREACHABLE
4147 operState := voltha.OperStatus_UNKNOWN
4148
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004149 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004150 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004151 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004152 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004153 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004154 case success := <-dh.chReconcilingFinished:
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304155 logger.Info(ctx, "reconciling finished signal received",
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004156 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4157 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4158 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4159 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4160 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4161 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4162 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4163 // However, a later refactoring of the functionality remains unaffected.
4164 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004165 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004166 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304167 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004168 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304169 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004170 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004171 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304172 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004173 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4174 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304175 operState = voltha.OperStatus_ACTIVE
4176 } else {
4177 operState = voltha.OperStatus_ACTIVATING
4178 }
4179 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4181 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4182 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304183 operState = voltha.OperStatus_DISCOVERED
4184 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004185 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004186 logger.Debugw(ctx, "Core DeviceStateUpdate",
4187 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304188 }
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304189 logger.Info(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004190 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004191 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004193 ConnStatus: connectStatus,
4194 OperStatus: operState,
4195 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304196 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004197 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304198 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004199 } else {
Maninderb5187552021-03-23 22:23:42 +05304200 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004201 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304202
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004203 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304204 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004205 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004206 } else {
4207 onuDevEntry.MutexPersOnuConfig.RLock()
4208 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4209 connectStatus = voltha.ConnectStatus_REACHABLE
4210 }
4211 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304212 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004213 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004214 }
mpagenko101ac942021-11-16 15:01:29 +00004215 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004216 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004217 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004218 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304219
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004220 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304221 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004222 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004223 } else {
4224 onuDevEntry.MutexPersOnuConfig.RLock()
4225 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4226 connectStatus = voltha.ConnectStatus_REACHABLE
4227 }
4228 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304229 }
4230
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004231 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304232
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004233 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004234 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004235 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004236 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004237 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004238
4239 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4240 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4241 } else {
4242 onuDevEntry.MutexReconciledTpInstances.Lock()
4243 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4244 onuDevEntry.MutexReconciledTpInstances.Unlock()
4245 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004246 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004247 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004248 dh.mutexReconcilingFlag.Lock()
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304249 if skipOnuConfig || dh.GetSkipOnuConfigEnabled() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004250 dh.reconciling = cSkipOnuConfigReconciling
4251 } else {
4252 dh.reconciling = cOnuConfigReconciling
4253 }
4254 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004255}
4256
mpagenko101ac942021-11-16 15:01:29 +00004257func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304258 logger.Warn(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004259 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004260 dh.sendChReconcileFinished(success)
4261 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4262 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4263 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004264 } else {
mpagenko101ac942021-11-16 15:01:29 +00004265 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004266 }
4267}
4268
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004269func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004270 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004271 defer dh.mutexReconcilingFlag.RUnlock()
4272 return dh.reconciling != cNoReconciling
4273}
4274
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004275func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004276 dh.mutexReconcilingFlag.RLock()
4277 defer dh.mutexReconcilingFlag.RUnlock()
4278 return dh.reconciling == cSkipOnuConfigReconciling
4279}
4280
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004281func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4282 dh.mutexReconcilingFirstPassFlag.Lock()
4283 dh.reconcilingFirstPass = value
4284 dh.mutexReconcilingFirstPassFlag.Unlock()
4285}
4286
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004287func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4288 dh.mutexReconcilingReasonUpdate.Lock()
4289 dh.reconcilingReasonUpdate = value
4290 dh.mutexReconcilingReasonUpdate.Unlock()
4291}
4292
4293func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4294 dh.mutexReconcilingReasonUpdate.RLock()
4295 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4296 return dh.reconcilingReasonUpdate
4297}
4298
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004299func (dh *deviceHandler) getDeviceReason() uint8 {
4300 dh.mutexDeviceReason.RLock()
4301 value := dh.deviceReason
4302 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004303 return value
4304}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004305
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004306func (dh *deviceHandler) GetDeviceReasonString() string {
4307 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004308}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004309
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004310func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004311 dh.mutexReadyForOmciConfig.Lock()
4312 dh.readyForOmciConfig = flagValue
4313 dh.mutexReadyForOmciConfig.Unlock()
4314}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004315func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004316 dh.mutexReadyForOmciConfig.RLock()
4317 flagValue := dh.readyForOmciConfig
4318 dh.mutexReadyForOmciConfig.RUnlock()
4319 return flagValue
4320}
Maninder7961d722021-06-16 22:10:28 +05304321
4322func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004323 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304324 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004325 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304326 }
4327
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004328 logger.Debugw(ctx, "Core DeviceStateUpdate",
4329 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004330 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004331 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004332 ConnStatus: connectStatus,
4333 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4334 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304335 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004336 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304337 }
4338}
khenaidoo7d3c5582021-08-11 18:09:44 -04004339
4340/*
4341Helper functions to communicate with Core
4342*/
4343
4344func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4345 cClient, err := dh.coreClient.GetCoreServiceClient()
4346 if err != nil || cClient == nil {
4347 return nil, err
4348 }
4349 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4350 defer cancel()
4351 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4352 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4353}
4354
khenaidoo42dcdfd2021-10-19 17:34:12 -04004355func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004356 cClient, err := dh.coreClient.GetCoreServiceClient()
4357 if err != nil || cClient == nil {
4358 return err
4359 }
4360 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4361 defer cancel()
4362 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004363 logger.Debugw(subCtx, "device-updated-in-core",
4364 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004365 return err
4366}
4367
4368func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4369 cClient, err := dh.coreClient.GetCoreServiceClient()
4370 if err != nil || cClient == nil {
4371 return err
4372 }
4373 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4374 defer cancel()
4375 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004376 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4377 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004378 return err
4379}
4380
4381func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4382 cClient, err := dh.coreClient.GetCoreServiceClient()
4383 if err != nil || cClient == nil {
4384 return err
4385 }
4386 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4387 defer cancel()
4388 _, err = cClient.DeviceUpdate(subCtx, device)
4389 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4390 return err
4391}
4392
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004393func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004394 cClient, err := dh.coreClient.GetCoreServiceClient()
4395 if err != nil || cClient == nil {
4396 return err
4397 }
4398 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4399 defer cancel()
4400 _, err = cClient.PortCreated(subCtx, port)
4401 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4402 return err
4403}
4404
khenaidoo42dcdfd2021-10-19 17:34:12 -04004405func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004406 cClient, err := dh.coreClient.GetCoreServiceClient()
4407 if err != nil || cClient == nil {
4408 return err
4409 }
4410 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4411 defer cancel()
4412 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004413 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 -04004414 return err
4415}
4416
khenaidoo42dcdfd2021-10-19 17:34:12 -04004417func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004418 cClient, err := dh.coreClient.GetCoreServiceClient()
4419 if err != nil || cClient == nil {
4420 return err
4421 }
4422 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4423 defer cancel()
4424 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004425 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 -04004426 return err
4427}
4428
4429/*
4430Helper functions to communicate with parent adapter
4431*/
4432
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004433func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4434 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4435
4436 var request = ia.TechProfileInstanceRequestMessage{
4437 DeviceId: dh.DeviceID,
4438 TpInstancePath: aTpPath,
4439 ParentDeviceId: dh.parentID,
4440 ParentPonPort: dh.device.ParentPortNo,
4441 OnuId: dh.device.ProxyAddress.OnuId,
4442 UniId: uint32(aUniID),
4443 }
4444
4445 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004446 if err != nil || pgClient == nil {
4447 return nil, err
4448 }
4449 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4450 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004451 logger.Debugw(subCtx, "get-tech-profile-instance",
4452 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004453 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004454}
4455
Girish Gowdrae95687a2021-09-08 16:30:58 -07004456// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4457// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4458func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4459 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4460 dh.setFlowMonitoringIsRunning(uniID, true)
4461 for {
4462 select {
4463 // block on the channel to receive an incoming flow
4464 // process the flow completely before proceeding to handle the next flow
4465 case flowCb := <-dh.flowCbChan[uniID]:
4466 startTime := time.Now()
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304467 logger.Info(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004468 respChan := make(chan error)
4469 if flowCb.addFlow {
4470 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4471 } else {
4472 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4473 }
4474 // Block on response and tunnel it back to the caller
4475 *flowCb.respChan <- <-respChan
nikesh.krishnan1ffb8132023-05-23 03:44:13 +05304476 logger.Info(flowCb.ctx, "serial-flow-processor--end",
Girish Gowdrae95687a2021-09-08 16:30:58 -07004477 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4478 case <-dh.stopFlowMonitoringRoutine[uniID]:
4479 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4480 dh.setFlowMonitoringIsRunning(uniID, false)
4481 return
4482 }
4483 }
4484}
4485
kesavand011d5162021-11-25 19:21:06 +05304486func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4487 request.ParentDeviceId = dh.GetProxyAddressID()
4488 request.ChildDeviceId = dh.DeviceID
4489 request.ProxyAddress = dh.GetProxyAddress()
4490 request.ConnectStatus = common.ConnectStatus_REACHABLE
4491
4492 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4493 if err != nil || pgClient == nil {
4494 return err
4495 }
4496 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4497 defer cancel()
4498 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4499 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4500 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004501 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4502 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304503 }
4504 return err
4505}
4506
khenaidoo42dcdfd2021-10-19 17:34:12 -04004507func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004508 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4509 if err != nil || pgClient == nil {
4510 return err
4511 }
4512 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4513 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004514 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004515 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004516 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4517 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004518 if status.Code(err) == codes.Unavailable {
4519 dh.setOltAvailable(false)
4520 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004521 logger.Errorw(ctx, "omci-failure",
4522 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004523 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004524 }
4525 return err
4526}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004527
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004528func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4529 // Check if there are additional TCONT instances necessary/available
4530 pDevEntry.MutexPersOnuConfig.Lock()
4531 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4532 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4533 pDevEntry.MutexPersOnuConfig.Unlock()
4534 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4535 logger.Debugw(ctx, "checking available TCONT instances",
4536 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4537 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4538 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4539 log.Fields{"device-id": dh.device.Id})
4540 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4541 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4542 }
4543 } else {
4544 pDevEntry.MutexPersOnuConfig.Unlock()
4545 }
4546 // Check if there are enough PrioQueue instances available
4547 if dh.pOnuTP != nil {
4548 var numberOfUsPrioQueueDbInsts int
4549
4550 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4551 for _, mgmtEntityID := range queueInstKeys {
4552 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4553 numberOfUsPrioQueueDbInsts++
4554 }
4555 }
4556 // Check if there is an upstream PriorityQueue instance available for each Gem port
4557 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4558 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4559 log.Fields{"device-id": dh.DeviceID,
4560 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4561 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4562 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4563
4564 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4565 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4566 log.Fields{"device-id": dh.device.Id})
4567 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4568 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4569 }
4570 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4571 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4572 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4573 } else {
4574 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4575 log.Fields{"device-id": dh.DeviceID})
4576 }
4577 return nil
4578}
4579
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004580// GetDeviceID - TODO: add comment
4581func (dh *deviceHandler) GetDeviceID() string {
4582 return dh.DeviceID
4583}
4584
4585// GetProxyAddressID - TODO: add comment
4586func (dh *deviceHandler) GetProxyAddressID() string {
4587 return dh.device.ProxyAddress.GetDeviceId()
4588}
4589
4590// GetProxyAddressType - TODO: add comment
4591func (dh *deviceHandler) GetProxyAddressType() string {
4592 return dh.device.ProxyAddress.GetDeviceType()
4593}
4594
4595// GetProxyAddress - TODO: add comment
4596func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4597 return dh.device.ProxyAddress
4598}
4599
4600// GetEventProxy - TODO: add comment
4601func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4602 return dh.EventProxy
4603}
4604
4605// GetOmciTimeout - TODO: add comment
4606func (dh *deviceHandler) GetOmciTimeout() int {
4607 return dh.pOpenOnuAc.omciTimeout
4608}
4609
4610// GetAlarmAuditInterval - TODO: add comment
4611func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4612 return dh.pOpenOnuAc.alarmAuditInterval
4613}
4614
4615// GetDlToOnuTimeout4M - TODO: add comment
4616func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4617 return dh.pOpenOnuAc.dlToOnuTimeout4M
4618}
4619
4620// GetUniEntityMap - TODO: add comment
4621func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4622 return &dh.uniEntityMap
4623}
4624
4625// GetPonPortNumber - TODO: add comment
4626func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4627 return &dh.ponPortNumber
4628}
4629
4630// GetUniVlanConfigFsm - TODO: add comment
4631func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004632 dh.lockVlanConfig.RLock()
4633 value := dh.UniVlanConfigFsmMap[uniID]
4634 dh.lockVlanConfig.RUnlock()
4635 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004636}
4637
4638// GetOnuAlarmManager - TODO: add comment
4639func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4640 return dh.pAlarmMgr
4641}
4642
4643// GetOnuMetricsManager - TODO: add comment
4644func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4645 return dh.pOnuMetricsMgr
4646}
4647
4648// GetOnuTP - TODO: add comment
4649func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4650 return dh.pOnuTP
4651}
4652
4653// GetBackendPathPrefix - TODO: add comment
4654func (dh *deviceHandler) GetBackendPathPrefix() string {
4655 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4656}
4657
4658// GetOnuIndication - TODO: add comment
4659func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4660 return dh.pOnuIndication
4661}
4662
4663// RLockMutexDeletionInProgressFlag - TODO: add comment
4664func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4665 dh.mutexDeletionInProgressFlag.RLock()
4666}
4667
4668// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4669func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4670 dh.mutexDeletionInProgressFlag.RUnlock()
4671}
4672
4673// GetDeletionInProgress - TODO: add comment
4674func (dh *deviceHandler) GetDeletionInProgress() bool {
4675 return dh.deletionInProgress
4676}
4677
4678// GetPmConfigs - TODO: add comment
4679func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4680 return dh.pmConfigs
4681}
4682
4683// GetDeviceType - TODO: add comment
4684func (dh *deviceHandler) GetDeviceType() string {
4685 return dh.DeviceType
4686}
4687
4688// GetLogicalDeviceID - TODO: add comment
4689func (dh *deviceHandler) GetLogicalDeviceID() string {
4690 return dh.logicalDeviceID
4691}
4692
4693// GetDevice - TODO: add comment
4694func (dh *deviceHandler) GetDevice() *voltha.Device {
4695 return dh.device
4696}
4697
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004698func (dh *deviceHandler) setOltAvailable(value bool) {
4699 dh.mutexOltAvailable.Lock()
4700 dh.oltAvailable = value
4701 dh.mutexOltAvailable.Unlock()
4702}
4703
4704// IsOltAvailable - TODO: add comment
4705func (dh *deviceHandler) IsOltAvailable() bool {
4706 dh.mutexOltAvailable.RLock()
4707 defer dh.mutexOltAvailable.RUnlock()
4708 return dh.oltAvailable
4709}
4710
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004711// GetMetricsEnabled - TODO: add comment
4712func (dh *deviceHandler) GetMetricsEnabled() bool {
4713 return dh.pOpenOnuAc.MetricsEnabled
4714}
4715
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004716// GetExtendedOmciSupportEnabled - TODO: add comment
4717func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4718 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4719}
4720
Praneeth Kumar Nalmas77ab2f32024-04-17 11:14:27 +05304721// GetExtendedOmciSupportEnabled - TODO: add comment
4722func (dh *deviceHandler) GetSkipOnuConfigEnabled() bool {
4723 return dh.pOpenOnuAc.skipOnuConfig
4724}
4725
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004726// InitPmConfigs - TODO: add comment
4727func (dh *deviceHandler) InitPmConfigs() {
4728 dh.pmConfigs = &voltha.PmConfigs{}
4729}
4730
4731// GetUniPortMask - TODO: add comment
4732func (dh *deviceHandler) GetUniPortMask() int {
4733 return dh.pOpenOnuAc.config.UniPortMask
4734}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004735
4736func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4737 tpPathFound := false
4738 for _, tpPath := range aTpPathMap {
4739 if tpPath != "" {
4740 tpPathFound = true
4741 }
4742 }
4743 return tpPathFound
4744}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004745
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304746func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4747 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4748 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4749 return resp
4750}
4751
Praneeth Kumar Nalmasaacc6122024-04-09 22:55:49 +05304752func (dh *deviceHandler) GetDeviceDeleteCommChan(ctx context.Context) chan bool {
4753 return dh.deviceDeleteCommChan
4754}
4755
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004756// PrepareForGarbageCollection - remove references to prepare for garbage collection
4757func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4758 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4759
4760 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4761 // first let the objects rest for some time to give all asynchronously started
4762 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004763 time.Sleep(2 * time.Second)
4764
4765 if dh.pOnuOmciDevice != nil {
4766 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4767 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4768 // reset handling (even in future coding), request monitoring is canceled here one last time to
4769 // be sure that all corresponding go routines are terminated
4770 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4771 }
4772 }
4773 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004774
4775 if dh.pOnuTP != nil {
4776 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4777 }
4778 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004779 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4780 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004781 select {
4782 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4783 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4784 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4785 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004786 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004787 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004788 }
4789 if dh.pAlarmMgr != nil {
4790 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4791 }
4792 if dh.pSelfTestHdlr != nil {
4793 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4794 }
4795 if dh.pLockStateFsm != nil {
4796 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4797 }
4798 if dh.pUnlockStateFsm != nil {
4799 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4800 }
4801 if dh.pOnuUpradeFsm != nil {
4802 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4803 }
4804 if dh.pOnuOmciDevice != nil {
4805 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4806 }
4807 for k, v := range dh.UniVlanConfigFsmMap {
4808 v.PrepareForGarbageCollection(ctx, aDeviceID)
4809 delete(dh.UniVlanConfigFsmMap, k)
4810 }
nikesh.krishnan1249be92023-11-27 04:20:12 +05304811 dh.pOnuIndication = nil
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004812 dh.pOnuOmciDevice = nil
4813 dh.pOnuTP = nil
4814 dh.pOnuMetricsMgr = nil
4815 dh.pAlarmMgr = nil
4816 dh.pSelfTestHdlr = nil
4817 dh.pLockStateFsm = nil
4818 dh.pUnlockStateFsm = nil
4819 dh.pOnuUpradeFsm = nil
4820}