blob: b9cadf091728b08e26999186fe0863c4e42d0710 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2020-2023 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
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000234}
235
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530236// newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400237func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530238 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400239 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400241 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000243 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.DeviceType = cloned.Type
245 dh.adminState = "up"
246 dh.device = cloned
247 dh.pOpenOnuAc = adapter
248 dh.exitChannel = make(chan int, 1)
249 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000250 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000251 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530253 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530254 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopHeartbeatCheck = make(chan bool, 2)
256 //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 +0000257 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000258 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000259 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000260 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000261 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300262 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000263 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000264 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000265 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000266 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300267 dh.disableDeviceRequested = false
Holger Hildebrandt2b107642022-12-09 07:56:23 +0000268 dh.oltAvailable = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000269 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000270 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
271 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
272 if rECSeconds < 2 {
273 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
274 rECSeconds = 2
275 }
276 rEVCSeconds := rECSeconds / 2
277 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000278 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000279 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000280 dh.pLastUpgradeImageState = &voltha.ImageState{
281 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
282 Reason: voltha.ImageState_UNKNOWN_ERROR,
283 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
284 }
285 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800287 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
288 dh.pmConfigs = cloned.PmConfigs
289 } /* else {
290 // will be populated when onu_metrics_mananger is initialized.
291 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 // Device related state machine
294 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000295 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000297 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
298 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
299 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
300 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
301 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000304 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
305 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
306 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
307 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
308 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
309 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
310 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
311 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000312 },
313 )
mpagenkoaf801632020-07-03 10:00:42 +0000314
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315 return &dh
316}
317
Himani Chawla6d2ae152020-09-02 13:11:20 +0530318// start save the device to the data model
319func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000320 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000322 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323}
324
Himani Chawla4d908332020-08-31 12:30:20 +0530325/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000326// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 logger.Debug("stopping-device-handler")
329 dh.exitChannel <- 1
330}
Himani Chawla4d908332020-08-31 12:30:20 +0530331*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332
333// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530334// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000335
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530336// adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530337func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400338 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000340 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000341 if dh.pDeviceStateFsm.Is(devStNull) {
342 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000343 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 +0000344 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000345 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800346 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
347 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800348 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400349 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800351 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800352 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000353 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000355 }
356
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000357}
358
khenaidoo42dcdfd2021-10-19 17:34:12 -0400359func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000360 /* 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 +0530361 //assuming omci message content is hex coded!
362 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000365 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000366 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530367 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000368 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000370 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000371 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
372 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
375 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530376}
377
khenaidoo42dcdfd2021-10-19 17:34:12 -0400378func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000380
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000381 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000382 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000383 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
384 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 if dh.pOnuTP == nil {
387 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000389 log.Fields{"device-id": dh.DeviceID})
390 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 if !dh.IsReadyForOmciConfig() {
393 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
394 "device-state": dh.GetDeviceReasonString()})
395 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000397 //previous state test here was just this one, now extended for more states to reject the SetRequest:
398 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
399 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530400
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
403 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 dh.pOnuTP.LockTpProcMutex()
405 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000406
mpagenko44bd8362021-11-15 11:40:05 +0000407 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000409 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410 }
411 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800413 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000414 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
415 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800416 return err
417 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000418 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
419 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000421 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530422
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400424 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000425 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
426 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000427
428 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
429 if err != nil {
430 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
431 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
432 // stopping all further processing
433 _ = dh.UpdateInterface(ctx)
434 return err
435 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700436 // if there has been some change for some uni TechProfilePath
437 //in order to allow concurrent calls to other dh instances we do not wait for execution here
438 //but doing so we can not indicate problems to the caller (who does what with that then?)
439 //by now we just assume straightforward successful execution
440 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
441 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530442
Girish Gowdra50e56422021-06-01 16:46:04 -0700443 // deadline context to ensure completion of background routines waited for
444 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
445 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
446 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700449
450 var wg sync.WaitGroup
451 wg.Add(1) // for the 1 go routine to finish
452 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000453 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700454 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000455 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
456 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 -0700457 return tpErr
458 }
459 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
460 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000461 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700464 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000465 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
466 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.DeviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700467 return kvErr
468 }
469 return nil
470 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000471 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700472 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700473 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000475 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000476 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
477 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530478 return nil
479}
480
khenaidoo42dcdfd2021-10-19 17:34:12 -0400481func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000482 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530483
484 if dh.pOnuTP == nil {
485 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 log.Fields{"device-id": dh.DeviceID})
488 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530489 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530490 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491 dh.pOnuTP.LockTpProcMutex()
492 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530493
mpagenko0f543222021-11-03 16:24:14 +0000494 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
495 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
496 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000497 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499 }
500 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800502 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000503 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
504 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800505 return err
506 }
mpagenko0f543222021-11-03 16:24:14 +0000507 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
508 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000509 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000510
Mahir Gunyel9545be22021-07-04 15:53:16 -0700511 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
Himani Chawla26e555c2020-08-31 12:30:20 +0530514}
515
khenaidoo42dcdfd2021-10-19 17:34:12 -0400516func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000517 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 +0000518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000519 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
522 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 if dh.pOnuTP == nil {
525 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 log.Fields{"device-id": dh.DeviceID})
528 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 }
530
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000532 dh.pOnuTP.LockTpProcMutex()
533 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000534
mpagenko0f543222021-11-03 16:24:14 +0000535 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
536 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
537 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000538 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000539 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000540 }
541 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700542 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000543 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800544 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000545 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
546 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800547 return err
548 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530550
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000551 var wg sync.WaitGroup
552 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
553 dctx, cancel := context.WithDeadline(context.Background(), deadline)
554 wg.Add(1)
555 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
556 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
557 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
558 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
559 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
560 return err
561 }
562
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565
Mahir Gunyel9545be22021-07-04 15:53:16 -0700566}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000567
Mahir Gunyel9545be22021-07-04 15:53:16 -0700568func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
570 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700571 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
573 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577 resourceName = "Gem"
578 } else {
579 resourceName = "Tcont"
580 }
581
582 // deadline context to ensure completion of background routines waited for
583 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
584 dctx, cancel := context.WithDeadline(context.Background(), deadline)
585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700587
588 var wg sync.WaitGroup
589 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700591 resource, entryID, &wg)
592 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
594 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700595 return err
596 }
597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
599 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
600 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
601 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 var wg2 sync.WaitGroup
603 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
604 wg2.Add(1)
605 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000606 logger.Debugw(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700608 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
610 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700611 return err
612 }
613 }
614 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700616 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530617 return nil
618}
619
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530620// FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400622 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400623 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700624 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
625 var errorsList []error
626 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000627 //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 +0000628 if apOfFlowChanges.ToRemove != nil {
629 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000630 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 "device-id": dh.DeviceID})
633 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700634 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000635 continue
636 }
637 flowInPort := flow.GetInPort(flowItem)
638 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000639 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
640 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700641 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000642 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000644 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000645 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000647 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000648 continue
649 } else {
650 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000651 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000652 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
653 loUniPort = uniPort
654 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000657 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000658 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700659 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000660 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000661 }
662 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
665 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700666
667 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
668 // Step1 : Fill flowControlBlock
669 // Step2 : Push the flowControlBlock to ONU channel
670 // Step3 : Wait on response channel for response
671 // Step4 : Return error value
672 startTime := time.Now()
673 respChan := make(chan error)
674 flowCb := FlowCb{
675 ctx: ctx,
676 addFlow: false,
677 flowItem: flowItem,
678 flowMetaData: nil,
679 uniPort: loUniPort,
680 respChan: &respChan,
681 }
682 dh.flowCbChan[loUniPort.UniID] <- flowCb
683 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
684 // Wait on the channel for flow handlers return value
685 retError = <-respChan
686 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
687 if retError != nil {
688 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
689 log.Fields{"device-id": dh.DeviceID, "error": retError})
690 errorsList = append(errorsList, retError)
691 continue
692 }
693 } else {
694 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
695 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000696 }
697 }
698 }
699 }
mpagenko01e726e2020-10-23 09:45:29 +0000700 if apOfFlowChanges.ToAdd != nil {
701 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
702 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000704 "device-id": dh.DeviceID})
705 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700706 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000707 continue
708 }
709 flowInPort := flow.GetInPort(flowItem)
710 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000711 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
712 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700713 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000714 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000715 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000716 } else if flowInPort == dh.ponPortNumber {
717 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000718 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000719 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000720 continue
721 } else {
722 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000723 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000724 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
725 loUniPort = uniPort
726 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000727 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000728 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000729 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000730 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700731 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000732 continue
mpagenko01e726e2020-10-23 09:45:29 +0000733 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000734 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
735 // if not, we just throw some error here to have an indication about that, if we really need to support that
736 // then we would need to create some means to activate the internal stored flows
737 // after the device gets active automatically (and still with its dependency to the TechProfile)
738 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
739 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000740 if !dh.IsReadyForOmciConfig() {
741 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
742 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700743 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
744 errorsList = append(errorsList, retError)
745 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000746 }
747
mpagenko01e726e2020-10-23 09:45:29 +0000748 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000749 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000750 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
751 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700752 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
753 // Step1 : Fill flowControlBlock
754 // Step2 : Push the flowControlBlock to ONU channel
755 // Step3 : Wait on response channel for response
756 // Step4 : Return error value
757 startTime := time.Now()
758 respChan := make(chan error)
759 flowCb := FlowCb{
760 ctx: ctx,
761 addFlow: true,
762 flowItem: flowItem,
763 flowMetaData: apFlowMetaData,
764 uniPort: loUniPort,
765 respChan: &respChan,
766 }
767 dh.flowCbChan[loUniPort.UniID] <- flowCb
768 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
769 // Wait on the channel for flow handlers return value
770 retError = <-respChan
771 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
772 if retError != nil {
773 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
774 log.Fields{"device-id": dh.DeviceID, "error": retError})
775 errorsList = append(errorsList, retError)
776 continue
777 }
778 } else {
779 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
780 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000781 }
782 }
783 }
784 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700785 if len(errorsList) > 0 {
786 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
787 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
788 }
789 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000790}
791
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530792// disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
793// following are the expected device states after this activity:
794// Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
mpagenkofc4f56e2020-11-04 17:17:49 +0000795// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
797 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300798 dh.mutexForDisableDeviceRequested.Lock()
799 dh.disableDeviceRequested = true
800 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000801 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 //note that disableDevice sequences in some 'ONU active' state may yield also
803 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000804 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000805 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000806 //disable-device shall be just a UNi/ONU-G related admin state setting
807 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000810 // disable UNI ports/ONU
811 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
812 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000814 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000817 }
818 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000819 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000821 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400822 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000824 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400825 OperStatus: voltha.OperStatus_UNKNOWN,
826 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000827 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000828 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000829 }
mpagenko01e726e2020-10-23 09:45:29 +0000830 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000831
832 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000833 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000834 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300835 }
836}
837
praneeth nalmas5a0a5502022-12-23 15:57:00 +0530838// reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
840 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000841
mpagenkoaa3afe92021-05-21 16:20:58 +0000842 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000843 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
844 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
845 // for real ONU's that should have nearly no influence
846 // Note that for real ONU's there is anyway a problematic situation with following sequence:
847 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
848 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
849 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000850 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000851
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000852 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300854 dh.mutexForDisableDeviceRequested.Lock()
855 dh.disableDeviceRequested = false
856 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000857 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000859 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000862 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300863}
864
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000869 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000870 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871 return
872 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000874 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000875 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000876 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000877 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000878 }
mpagenko101ac942021-11-16 15:01:29 +0000879 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000880 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000881 }
Himani Chawla4d908332020-08-31 12:30:20 +0530882 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 pDevEntry.MutexPersOnuConfig.RLock()
884 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
885 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
886 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
887 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
888 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000890}
891
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000892func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000894
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000895 continueWithFlowConfig := false
896
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000898 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000899 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000900 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
901 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 dh.pOnuTP.LockTpProcMutex()
904 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000905
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000907 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000908 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
909 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000910 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000912 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
913 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000914 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000915 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 techProfsFound := false
917 techProfInstLoadFailed := false
918outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000919 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000920 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000922 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000923 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000924 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000925 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
928 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000929 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000931 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000933 var iaTechTpInst ia.TechProfileDownloadMessage
934 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800935 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 pDevEntry.MutexReconciledTpInstances.RLock()
937 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
938 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000939 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000940 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700941 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000942 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700943 break outerLoop
944 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000945 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000946 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 var tpInst tech_profile.TechProfileInstance
948 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400949 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700950 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000951 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", 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 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000954 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700956 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
957 break outerLoop
958 }
959
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 // deadline context to ensure completion of background routines waited for
961 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
962 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000963 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000964
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800966 var wg sync.WaitGroup
967 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000969 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000970 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
971 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700972 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
973 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800974 }
mpagenko2dc896e2021-08-02 12:03:59 +0000975 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 if len(uniData.PersFlowParams) != 0 {
977 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000978 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000980 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000981 } // for all UNI entries from SOnuPersistentData
982 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
983 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000984 }
mpagenko2dc896e2021-08-02 12:03:59 +0000985
986 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
987 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000988
989 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000990}
991
992func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
993 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
994 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000995 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000997 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000998 return
999 }
mpagenko2dc896e2021-08-02 12:03:59 +00001000 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001001 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +00001002 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -07001003 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001004 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001005 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 }
mpagenko2dc896e2021-08-02 12:03:59 +00001007 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001009 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001010 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001011 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012}
1013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1015 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001016
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001017 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001018 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001019 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001020 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001021 return
1022 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 pDevEntry.MutexPersOnuConfig.RLock()
1025 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1026 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001029 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001030 return
1031 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001032 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001033 var uniVlanConfigEntries []uint8
1034 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1035
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001037 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1038 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001039 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001041 continue
1042 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001043 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001044 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001045 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001046 // It doesn't make sense to configure any flows if no TPs are available
1047 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001048 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1050 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001051 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001055 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001056 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001058 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1059 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001060 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001061 return
1062 }
mpagenko101ac942021-11-16 15:01:29 +00001063 //needed to split up function due to sca complexity
1064 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1065
mpagenko2dc896e2021-08-02 12:03:59 +00001066 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001067 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1069 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001070 // this can't be used as global finished reconciling flag because
1071 // assumes is getting called before the state machines for the last flow is completed,
1072 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1074 } // for all UNI entries from SOnuPersistentData
1075 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001076
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001077 if !flowsFound {
1078 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001080 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001081 return
1082 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001083 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1084 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1085 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1086 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1087 log.Fields{"device-id": dh.DeviceID})
1088 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1089 if pDevEntry != nil {
1090 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001091 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001092 } else {
1093 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1094 log.Fields{"device-id": dh.DeviceID})
1095 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1096 if pDevEntry != nil {
1097 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1098 }
1099 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001100 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001101 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001102}
1103
mpagenko101ac942021-11-16 15:01:29 +00001104func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1105 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1106 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1107 flowsProcessed := 0
1108 lastFlowToReconcile := false
1109 loUniID := apUniPort.UniID
1110 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001111 if !(*apFlowsFound) {
1112 *apFlowsFound = true
1113 syncChannel := make(chan struct{})
1114 // start go routine with select() on reconciling vlan config channel before
1115 // starting vlan config reconciling process to prevent loss of any signal
1116 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1117 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1118 //block until the wait routine is really blocked on channel input
1119 // in order to prevent to early ready signal from VlanConfig processing
1120 <-syncChannel
1121 }
1122 if flowsProcessed == len(aPersFlowParam)-1 {
1123 var uniAdded bool
1124 lastFlowToReconcile = true
1125 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1126 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001127 }
1128 }
mpagenko101ac942021-11-16 15:01:29 +00001129 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1130 "device-id": dh.DeviceID, "uni-id": loUniID,
1131 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1132 dh.lockVlanConfig.Lock()
1133 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1134 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1135 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301136 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 +00001137 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1138 }
1139 } else {
1140 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301141 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301142 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001143 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1144 }
1145 }
1146 dh.lockVlanConfig.Unlock()
1147 flowsProcessed++
1148 } //for all flows of this UNI
1149}
1150
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301151// waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1152//
1153// and decrements the according handler wait group waiting for these indications
mpagenko101ac942021-11-16 15:01:29 +00001154func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1155 waitGroup *cmn.WaitGroupWithTimeOut) {
1156 var reconciledUniVlanConfigEntries []uint8
1157 var appended bool
1158 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1159 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1160 "device-id": dh.DeviceID, "expiry": expiry})
1161 // indicate blocking on channel now to the caller
1162 aSyncChannel <- struct{}{}
1163 for {
1164 select {
1165 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1166 switch uniIndication {
1167 // no activity requested (should normally not be received) - just continue waiting
1168 case cWaitReconcileFlowNoActivity:
1169 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1170 case cWaitReconcileFlowAbortOnError:
1171 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1172 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1173 return
1174 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1175 case cWaitReconcileFlowAbortOnSuccess:
1176 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1177 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1178 return
1179 // this should be a valid UNI vlan config done indication
1180 default:
1181 if uniIndication < platform.MaxUnisPerOnu {
1182 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1183 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1184 if reconciledUniVlanConfigEntries, appended =
1185 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1186 waitGroup.Done()
1187 }
1188 } else {
1189 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1190 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1191 }
1192 } //switch uniIndication
1193
1194 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1195 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1196 log.Fields{"device-id": dh.DeviceID})
1197 return
1198 }
1199 }
1200}
1201
1202func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1203 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1204}
1205
1206func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1207 for _, ele := range slice {
1208 if ele == val {
1209 return slice, false
1210 }
1211 }
1212 return append(slice, val), true
1213}
1214
1215// sendChReconcileFinished - sends true or false on reconcileFinish channel
1216func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1217 if dh != nil { //if the object still exists (might have been already deleted in background)
1218 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1219 select {
1220 case dh.chReconcilingFinished <- success:
1221 default:
1222 }
1223 }
1224}
1225
1226// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1227func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1228 if dh != nil { //if the object still exists (might have been already deleted in background)
1229 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1230 select {
1231 case dh.chUniVlanConfigReconcilingDone <- value:
1232 default:
1233 }
1234 }
1235}
1236
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001241 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001242 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001243 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001244 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001245 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001246
1247 // deadline context to ensure completion of background routines waited for
1248 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +05301249 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001251
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001252 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001253
1254 var wg sync.WaitGroup
1255 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001258
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001259 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001260 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001261}
1262
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301263// func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
mpagenko15ff4a52021-03-02 10:09:20 +00001264// before this change here return like this was used:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301265//
1266// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
1267//
1268// was and is called in background - error return does not make sense
mpagenko15ff4a52021-03-02 10:09:20 +00001269func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001270 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001271 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001273 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001274 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301276 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001278 return
Himani Chawla4d908332020-08-31 12:30:20 +05301279 }
mpagenko01e726e2020-10-23 09:45:29 +00001280
1281 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001283
mpagenko44bd8362021-11-15 11:40:05 +00001284 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001286 // 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 -04001287 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001289 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001290 OperStatus: voltha.OperStatus_DISCOVERED,
1291 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001292 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001294 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001295 }
mpagenkoe4782082021-11-25 12:04:26 +00001296 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001297 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001298 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001300 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1301 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1302 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1303 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001304}
1305
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301306// doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
1307//
1308// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001309func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001311 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001312 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001313
1314 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001315 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001316 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1318 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001319 }
1320
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001321 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001322 var inactiveImageID uint16
1323 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1324 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001325 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1326 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001327 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001328 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001329 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001330 if err == nil {
1331 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1332 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001334 }
1335 } else {
1336 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001338 }
mpagenko15ff4a52021-03-02 10:09:20 +00001339 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001340 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001341 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001342 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1343 dh.upgradeCanceled = true
1344 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1345 }
mpagenko38662d02021-08-11 09:45:19 +00001346 //no effort spent anymore for the old API to automatically cancel and restart the download
1347 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001348 }
mpagenko15ff4a52021-03-02 10:09:20 +00001349 } else {
1350 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001352 }
1353 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1355 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001356 }
1357 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001358}
1359
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301360// onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
mpagenkoc26d4c02021-05-06 14:27:57 +00001361// after the OnuImage has been downloaded to the adapter, called in background
1362func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001364
1365 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001367 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001369 return
1370 }
1371
1372 var inactiveImageID uint16
1373 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1374 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001375 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001376
mpagenko59862f02021-10-11 08:53:18 +00001377 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001378 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001379 // but must be still locked at calling createOnuUpgradeFsm
1380 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1381 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1382 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001383 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1384 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 //flush the remove upgradeFsmChan channel
1387 select {
1388 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001389 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001390 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001391 }
mpagenko59862f02021-10-11 08:53:18 +00001392 dh.lockUpgradeFsm.Unlock()
1393 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1394 dh.upgradeCanceled = true
1395 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1396 }
mpagenko38662d02021-08-11 09:45:19 +00001397 select {
1398 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001400 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1401 return
1402 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001404 }
mpagenko59862f02021-10-11 08:53:18 +00001405 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001406 }
mpagenko38662d02021-08-11 09:45:19 +00001407
1408 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001409 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001410 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001412 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001413 if err == nil {
1414 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1415 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1416 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001418 return
1419 }
mpagenko38662d02021-08-11 09:45:19 +00001420 } else {
1421 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001423 }
1424 return
1425 }
1426 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001427 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001428}
1429
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301430// onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001431func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1432 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001433 var err error
1434 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1435 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1436 // 2.) activation of the inactive image
1437
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001438 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001439 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001440 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1441 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001442 }
1443 dh.lockUpgradeFsm.RLock()
1444 if dh.pOnuUpradeFsm != nil {
1445 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001446 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001447 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1449 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001450 }
mpagenko59862f02021-10-11 08:53:18 +00001451 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1452 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1453 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1454 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001455 // use the OnuVendor identification from this device for the internal unique name
1456 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001457 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001458 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001459 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001460 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 "device-id": dh.DeviceID, "error": err})
1462 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001463 }
mpagenko183647c2021-06-08 15:25:04 +00001464 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001465 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001466 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001467 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001468 } //else
1469 dh.lockUpgradeFsm.RUnlock()
1470
1471 // 2.) check if requested image-version equals the inactive one and start its activation
1472 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1473 var inactiveImageID uint16
1474 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1475 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1477 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001478 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001479 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001480 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001481 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001482 if err == nil {
1483 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1484 inactiveImageID, aCommitRequest); err != nil {
1485 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 "device-id": dh.DeviceID, "error": err})
1487 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001488 }
1489 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001491 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001492 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 } //else
1494 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001495 "device-id": dh.DeviceID, "error": err})
1496 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001497}
1498
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301499// onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001500func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1501 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001502 var err error
1503 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1504 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1505 // 2.) commitment of the active image
1506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001507 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001508 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001509 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1510 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001511 }
1512 dh.lockUpgradeFsm.RLock()
1513 if dh.pOnuUpradeFsm != nil {
1514 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1518 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001519 }
mpagenko59862f02021-10-11 08:53:18 +00001520 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1521 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1522 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1523 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001524 // use the OnuVendor identification from this device for the internal unique name
1525 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001526 // 1.) check a started upgrade process and relay the commitment request to it
1527 // the running upgrade may be based either on the imageIdentifier (started from download)
1528 // or on the imageVersion (started from pure activation)
1529 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1530 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001531 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 "device-id": dh.DeviceID, "error": err})
1533 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 }
mpagenko183647c2021-06-08 15:25:04 +00001535 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001537 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001538 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 } //else
1540 dh.lockUpgradeFsm.RUnlock()
1541
mpagenko183647c2021-06-08 15:25:04 +00001542 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001543 var activeImageID uint16
1544 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1545 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1547 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001548 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001549 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001550 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001551 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001552 if err == nil {
1553 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1554 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 "device-id": dh.DeviceID, "error": err})
1556 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001557 }
1558 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001559 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001560 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001561 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001562 } //else
1563 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 "device-id": dh.DeviceID, "error": err})
1565 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001566}
1567
mpagenkoaa3afe92021-05-21 16:20:58 +00001568func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001569 aVersion string) *voltha.ImageState {
1570 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001571 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001572 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001573 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001574 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1575 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1576 if aVersion == dh.pLastUpgradeImageState.Version {
1577 pImageState = dh.pLastUpgradeImageState
1578 } else { //state request for an image version different from last processed image version
1579 pImageState = &voltha.ImageState{
1580 Version: aVersion,
1581 //we cannot state something concerning this version
1582 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1583 Reason: voltha.ImageState_NO_ERROR,
1584 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1585 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001586 }
1587 }
mpagenko38662d02021-08-11 09:45:19 +00001588 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001589}
1590
1591func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1592 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001593 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001594 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001595 dh.lockUpgradeFsm.RLock()
1596 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001597 dh.lockUpgradeFsm.RUnlock()
1598 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001599 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001600 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1601 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1602 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1603 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1604 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1605 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001606 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1607 dh.upgradeCanceled = true
1608 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1609 }
mpagenko45586762021-10-01 08:30:22 +00001610 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001611 } else {
mpagenko45586762021-10-01 08:30:22 +00001612 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001613 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1614 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1615 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1616 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1617 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1618 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001619 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1620 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001621 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1622 //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 +00001623 }
1624}
1625
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001626func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1627
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001629
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001630 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001631 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1633 pDevEntry.MutexOnuImageStatus.Lock()
1634 pDevEntry.POnuImageStatus = onuImageStatus
1635 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001636
1637 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001639 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1640 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1642 pDevEntry.MutexOnuImageStatus.Lock()
1643 pDevEntry.POnuImageStatus = nil
1644 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001645 return images, err
1646}
1647
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649// #####################################################################################
1650
1651// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301652// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001655 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1656 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657}
1658
1659// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001662 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001663 var err error
1664
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001665 // populate what we know. rest comes later after mib sync
1666 dh.device.Root = false
1667 dh.device.Vendor = "OpenONU"
1668 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001669 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001670 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001671
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001672 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001673
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 if !dh.IsReconciling() {
1675 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001676 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1677 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1678 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301679 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001680 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001683 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684
Himani Chawla4d908332020-08-31 12:30:20 +05301685 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001686 dh.ponPortNumber = dh.device.ParentPortNo
1687
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1689 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1690 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301693 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001694
1695 /*
1696 self._pon = PonPort.create(self, self._pon_port_number)
1697 self._pon.add_peer(self.parent_id, self._pon_port_number)
1698 self.logger.debug('adding-pon-port-to-agent',
1699 type=self._pon.get_port().type,
1700 admin_state=self._pon.get_port().admin_state,
1701 oper_status=self._pon.get_port().oper_status,
1702 )
1703 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001704 if !dh.IsReconciling() {
1705 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001706 var ponPortNo uint32 = 1
1707 if dh.ponPortNumber != 0 {
1708 ponPortNo = dh.ponPortNumber
1709 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001711 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001712 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001713 PortNo: ponPortNo,
1714 Label: fmt.Sprintf("pon-%d", ponPortNo),
1715 Type: voltha.Port_PON_ONU,
1716 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301717 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001718 PortNo: ponPortNo}}, // Peer port is parent's port number
1719 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001720 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001721 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001722 e.Cancel(err)
1723 return
1724 }
1725 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001726 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001727 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001728 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729}
1730
1731// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001733
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001734 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 var err error
1736 /*
1737 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1738 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1739 return nil
1740 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001742 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001743 e.Cancel(err)
1744 return
1745 }
1746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001747 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001749 // reconcilement will be continued after mib download is done
1750 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001751
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 /*
1753 ############################################################################
1754 # Setup Alarm handler
1755 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1756 device.serial_number)
1757 ############################################################################
1758 # Setup PM configuration for this device
1759 # Pass in ONU specific options
1760 kwargs = {
1761 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1762 'heartbeat': self.heartbeat,
1763 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1764 }
1765 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1766 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1767 self.logical_device_id, device.serial_number,
1768 grouped=True, freq_override=False, **kwargs)
1769 pm_config = self._pm_metrics.make_proto()
1770 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1771 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1772 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1773
1774 # Note, ONU ID and UNI intf set in add_uni_port method
1775 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1776 ani_ports=[self._pon])
1777
1778 # Code to Run OMCI Test Action
1779 kwargs_omci_test_action = {
1780 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1781 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1782 }
1783 serial_number = device.serial_number
1784 self._test_request = OmciTestRequest(self.core_proxy,
1785 self.omci_agent, self.device_id,
1786 AniG, serial_number,
1787 self.logical_device_id,
1788 exclusive=False,
1789 **kwargs_omci_test_action)
1790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001791 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001792 else:
1793 self.logger.info('onu-already-activated')
1794 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001795
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001796 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001797}
1798
1799// doStateConnected get the device info and update to voltha core
1800// for comparison of the original method (not that easy to uncomment): compare here:
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301801//
1802// voltha-openolt-adapter/adaptercore/device_handler.go
1803// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001806 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301807 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001808 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001809 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001810}
1811
1812// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001815 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301816 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001818 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819
1820 /*
1821 // Synchronous call to update device state - this method is run in its own go routine
1822 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1823 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001824 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 +00001825 return err
1826 }
1827 return nil
1828 */
1829}
1830
1831// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001834 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001835 var err error
1836
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001837 device := dh.device
1838 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001839 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001841 e.Cancel(err)
1842 return
1843 }
1844
1845 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001847 /*
1848 // Update the all ports state on that device to disable
1849 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001850 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001851 return er
1852 }
1853
1854 //Update the device oper state and connection status
1855 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1856 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1857 dh.device = cloned
1858
1859 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001860 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001861 return er
1862 }
1863
1864 //get the child device for the parent device
1865 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1866 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001867 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001868 return err
1869 }
1870 for _, onuDevice := range onuDevices.Items {
1871
1872 // Update onu state as down in onu adapter
1873 onuInd := oop.OnuIndication{}
1874 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001875 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001876 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1877 if er != nil {
1878 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001879 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880 //Do not return here and continue to process other ONUs
1881 }
1882 }
1883 // * Discovered ONUs entries need to be cleared , since after OLT
1884 // is up, it starts sending discovery indications again* /
1885 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001886 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001887 return nil
1888 */
Himani Chawla4d908332020-08-31 12:30:20 +05301889 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001890 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001891 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001892}
1893
Himani Chawla6d2ae152020-09-02 13:11:20 +05301894// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001895// #################################################################################
1896
1897// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301898// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001899
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301900// GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001901func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001902 dh.lockDevice.RLock()
1903 pOnuDeviceEntry := dh.pOnuOmciDevice
1904 if aWait && pOnuDeviceEntry == nil {
1905 //keep the read sema short to allow for subsequent write
1906 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001908 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1909 // so it might be needed to wait here for that event with some timeout
1910 select {
1911 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001912 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001913 return nil
1914 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001915 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001916 // if written now, we can return the written value without sema
1917 return dh.pOnuOmciDevice
1918 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001919 }
mpagenko3af1f032020-06-10 08:53:41 +00001920 dh.lockDevice.RUnlock()
1921 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922}
1923
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301924// setDeviceHandlerEntries sets the ONU device entry within the handler
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001925func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1926 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001927 dh.lockDevice.Lock()
1928 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001929 dh.pOnuOmciDevice = apDeviceEntry
1930 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001931 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301932 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001933 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001934}
1935
praneeth nalmas5a0a5502022-12-23 15:57:00 +05301936// addOnuDeviceEntry creates a new ONU device or returns the existing
Himani Chawla6d2ae152020-09-02 13:11:20 +05301937func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001939
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001940 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001941 if deviceEntry == nil {
1942 /* costum_me_map in python code seems always to be None,
1943 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1944 /* also no 'clock' argument - usage open ...*/
1945 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001946 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1947 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1948 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1949 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1950 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001951 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001953 // fire deviceEntry ready event to spread to possibly waiting processing
1954 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001956 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001957 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001958 }
1959 // might be updated with some error handling !!!
1960 return nil
1961}
1962
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001964 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001965 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1966
1967 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001968
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001970 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1972 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001973 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 if !dh.IsReconciling() {
1975 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001977 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001978 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001980 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001981
khenaidoo42dcdfd2021-10-19 17:34:12 -04001982 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001984 OperStatus: voltha.OperStatus_ACTIVATING,
1985 ConnStatus: voltha.ConnectStatus_REACHABLE,
1986 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001987 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001989 }
1990 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001992 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001993
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001994 pDevEntry.MutexPersOnuConfig.RLock()
1995 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1996 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001998 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001999 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002000 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002001 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002002 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002003 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002004 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2005 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2006 // 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 +00002007 // 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 +00002008 // so let's just try to keep it simple ...
2009 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002011 if err != nil || device == nil {
2012 //TODO: needs to handle error scenarios
2013 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2014 return errors.New("Voltha Device not found")
2015 }
2016 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002017
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002018 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002019 return err
mpagenko3af1f032020-06-10 08:53:41 +00002020 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002021 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002022
2023 /* this might be a good time for Omci Verify message? */
2024 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002025 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002026 dh.device.Id, pDevEntry.PDevOmciCC, false,
mpagenko900ee4b2020-10-12 11:56:34 +00002027 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002028 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002029
2030 /* give the handler some time here to wait for the OMCi verification result
2031 after Timeout start and try MibUpload FSM anyway
2032 (to prevent stopping on just not supported OMCI verification from ONU) */
2033 select {
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002034 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002035 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002036 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002037 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002038 }
2039
2040 /* In py code it looks earlier (on activate ..)
2041 # Code to Run OMCI Test Action
2042 kwargs_omci_test_action = {
2043 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2044 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2045 }
2046 serial_number = device.serial_number
2047 self._test_request = OmciTestRequest(self.core_proxy,
2048 self.omci_agent, self.device_id,
2049 AniG, serial_number,
2050 self.logical_device_id,
2051 exclusive=False,
2052 **kwargs_omci_test_action)
2053 ...
2054 # Start test requests after a brief pause
2055 if not self._test_request_started:
2056 self._test_request_started = True
2057 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2058 reactor.callLater(tststart, self._test_request.start_collector)
2059
2060 */
2061 /* which is then: in omci_test_request.py : */
2062 /*
2063 def start_collector(self, callback=None):
2064 """
2065 Start the collection loop for an adapter if the frequency > 0
2066
2067 :param callback: (callable) Function to call to collect PM data
2068 """
2069 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2070 if callback is None:
2071 callback = self.perform_test_omci
2072
2073 if self.lc is None:
2074 self.lc = LoopingCall(callback)
2075
2076 if self.default_freq > 0:
2077 self.lc.start(interval=self.default_freq / 10)
2078
2079 def perform_test_omci(self):
2080 """
2081 Perform the initial test request
2082 """
2083 ani_g_entities = self._device.configuration.ani_g_entities
2084 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2085 is not None else None
2086 self._entity_id = ani_g_entities_ids[0]
2087 self.logger.info('perform-test', entity_class=self._entity_class,
2088 entity_id=self._entity_id)
2089 try:
2090 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2091 result = yield self._device.omci_cc.send(frame)
2092 if not result.fields['omci_message'].fields['success_code']:
2093 self.logger.info('Self-Test Submitted Successfully',
2094 code=result.fields[
2095 'omci_message'].fields['success_code'])
2096 else:
2097 raise TestFailure('Test Failure: {}'.format(
2098 result.fields['omci_message'].fields['success_code']))
2099 except TimeoutError as e:
2100 self.deferred.errback(failure.Failure(e))
2101
2102 except Exception as e:
2103 self.logger.exception('perform-test-Error', e=e,
2104 class_id=self._entity_class,
2105 entity_id=self._entity_id)
2106 self.deferred.errback(failure.Failure(e))
2107
2108 */
2109
2110 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002111 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002112
mpagenko1cc3cb42020-07-27 15:24:38 +00002113 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2114 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2115 * 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 +05302116 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002117 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002118 //call MibUploadFSM - transition up to state UlStInSync
2119 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002120 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002121 if pMibUlFsm.Is(mib.UlStDisabled) {
2122 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2123 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2124 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302125 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002126 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302127 //Determine ONU status and start/re-start MIB Synchronization tasks
2128 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002129 if pDevEntry.IsNewOnu() {
2130 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2131 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2132 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002133 }
Himani Chawla4d908332020-08-31 12:30:20 +05302134 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002135 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2136 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2137 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302138 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002139 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002141 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002143 "device-id": dh.DeviceID})
2144 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002145 }
2146 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002147 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2148 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002149 }
2150 return nil
2151}
2152
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002153func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002154 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002155 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002156 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2157 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002158
mpagenko900ee4b2020-10-12 11:56:34 +00002159 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2160 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2161 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002162 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002164 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002165 // abort: system behavior is just unstable ...
2166 return err
2167 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002168 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002169 _ = 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 +00002170
2171 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002172 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002174 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002175 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2176 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002177 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002178 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002179
2180 //TODO!!! remove existing traffic profiles
2181 /* from py code, if TP's exist, remove them - not yet implemented
2182 self._tp = dict()
2183 # Let TP download happen again
2184 for uni_id in self._tp_service_specific_task:
2185 self._tp_service_specific_task[uni_id].clear()
2186 for uni_id in self._tech_profile_download_done:
2187 self._tech_profile_download_done[uni_id].clear()
2188 */
2189
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002190 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002191
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002193
mpagenkoe4782082021-11-25 12:04:26 +00002194 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002195 // abort: system behavior is just unstable ...
2196 return err
2197 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002199 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002200 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002201 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002202 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2203 OperStatus: voltha.OperStatus_DISCOVERED,
2204 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002205 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002208 // abort: system behavior is just unstable ...
2209 return err
2210 }
2211 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002213 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002214 return nil
2215}
2216
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002217func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002218 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2219 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2220 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2221 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002222 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002223
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002225 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2227 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002228 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002229 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002230 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002231 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002232 pDevEntry.MutexOnuImageStatus.RLock()
2233 if pDevEntry.POnuImageStatus != nil {
2234 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002235 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002237
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002238 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002239 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002240 }
2241 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002243 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002244 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002245 }
mpagenko101ac942021-11-16 15:01:29 +00002246 //stop any deviceHandler reconcile processing (if running)
2247 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002248 //port lock/unlock FSM's may be active
2249 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002251 }
2252 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002253 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002254 }
2255 //techProfile related PonAniConfigFsm FSM may be active
2256 if dh.pOnuTP != nil {
2257 // should always be the case here
2258 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002259 if dh.pOnuTP.PAniConfigFsm != nil {
2260 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2261 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002262 }
mpagenko900ee4b2020-10-12 11:56:34 +00002263 }
2264 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002265 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002266 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002267 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002268 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002269 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002270 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002271 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002272 } else {
2273 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002274 }
2275 }
2276 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002278 // Stop collector routine
2279 dh.stopCollector <- true
2280 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302282 dh.stopAlarmManager <- true
2283 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002284 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002285 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002286 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302287
Girish Gowdrae95687a2021-09-08 16:30:58 -07002288 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2289
mpagenko80622a52021-02-09 16:53:23 +00002290 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002292 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002293 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002295 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002296 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002297 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2298 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2299 // (even though it may also run into direct cancellation, a bit hard to verify here)
2300 // so don't set 'dh.upgradeCanceled = true' here!
2301 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2302 }
mpagenko38662d02021-08-11 09:45:19 +00002303 }
mpagenko80622a52021-02-09 16:53:23 +00002304
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002306 return nil
2307}
2308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2310 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 +05302311
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002312 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002314 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002315 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002316 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002317 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002319
mpagenkoa40e99a2020-11-17 13:50:39 +00002320 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2321 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2322 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2323 * disable/enable toggling here to allow traffic
2324 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2325 * like the py comment says:
2326 * # start by locking all the unis till mib sync and initial mib is downloaded
2327 * # this way we can capture the port down/up events when we are ready
2328 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302329
mpagenkoa40e99a2020-11-17 13:50:39 +00002330 // Init Uni Ports to Admin locked state
2331 // *** should generate UniLockStateDone event *****
2332 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002334 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002337 }
2338}
2339
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2341 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302342 /* Mib download procedure -
2343 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2344 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002346 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002348 return
2349 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002350 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302351 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002352 if pMibDlFsm.Is(mib.DlStDisabled) {
2353 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2354 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 +05302355 // maybe try a FSM reset and then again ... - TODO!!!
2356 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002357 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2360 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302361 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002362 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302363 //Begin MIB data download (running autonomously)
2364 }
2365 }
2366 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002367 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 // maybe try a FSM reset and then again ... - TODO!!!
2370 }
2371 /***** Mib download started */
2372 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002373 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 }
2375}
2376
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002377func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2378 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002379 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2380 if pDevEntry == nil {
2381 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2382 return
2383 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002385 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002387 // update device info in core
2388 pDevEntry.MutexPersOnuConfig.RLock()
2389 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2390 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2391 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2392 pDevEntry.MutexPersOnuConfig.RUnlock()
2393 dh.logicalDeviceID = dh.DeviceID
2394 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2395 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2396 }
2397 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002398 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2399 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2400 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2401 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002402 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002404 ConnStatus: voltha.ConnectStatus_REACHABLE,
2405 OperStatus: voltha.OperStatus_ACTIVE,
2406 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302407 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002410 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 }
2412 } else {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002413 logger.Debugw(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002414 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302415 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002416 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002417
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002418 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002419 var waitForOmciProcessor sync.WaitGroup
2420 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002421 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002422 go dh.StartCollector(ctx, &waitForOmciProcessor)
2423 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002424 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002425 if !dh.GetAlarmManagerIsRunning(ctx) {
2426 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002427 }
2428
Girish Gowdrae95687a2021-09-08 16:30:58 -07002429 // Start flow handler routines per UNI
2430 for _, uniPort := range dh.uniEntityMap {
2431 // only if this port was enabled for use by the operator at startup
2432 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2433 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2434 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2435 }
2436 }
2437 }
2438
Girish Gowdrae0140f02021-02-02 16:55:09 -08002439 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002440 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002441 // There is no way we should be landing here, but if we do then
2442 // there is nothing much we can do about this other than log error
2443 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2444 }
2445
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002448 pDevEntry.MutexPersOnuConfig.RLock()
2449 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2450 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002451 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002452 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002453 dh.mutexForDisableDeviceRequested.Lock()
2454 dh.disableDeviceRequested = true
2455 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002456 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002457 // reconcilement will be continued after ani config is done
2458 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002460 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002461 dh.mutexForDisableDeviceRequested.RLock()
2462 if !dh.disableDeviceRequested {
2463 if dh.pUnlockStateFsm == nil {
2464 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2465 } else { //UnlockStateFSM already init
2466 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2467 dh.runUniLockFsm(ctx, false)
2468 }
2469 dh.mutexForDisableDeviceRequested.RUnlock()
2470 } else {
2471 dh.mutexForDisableDeviceRequested.RUnlock()
2472 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002473 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302474 }
2475}
2476
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2478 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302479
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002480 if !dh.IsReconciling() {
2481 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002482 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2484 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002485 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002487 return
2488 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 pDevEntry.MutexPersOnuConfig.Lock()
2490 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2491 pDevEntry.MutexPersOnuConfig.Unlock()
2492 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002495 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302496 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Debugw(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002499 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002500 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302501 }
2502}
2503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002504func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002505 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002507
mpagenko44bd8362021-11-15 11:40:05 +00002508 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002509 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002511 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002512 OperStatus: voltha.OperStatus_UNKNOWN,
2513 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002514 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002516 }
2517
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002519 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002520 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002521
2522 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002524
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002527 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002528 return
2529 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 pDevEntry.MutexPersOnuConfig.Lock()
2531 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2532 pDevEntry.MutexPersOnuConfig.Unlock()
2533 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002535 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002536 }
mpagenko900ee4b2020-10-12 11:56:34 +00002537}
2538
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002539func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002542 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002544 ConnStatus: voltha.ConnectStatus_REACHABLE,
2545 OperStatus: voltha.OperStatus_ACTIVE,
2546 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002547 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002549 }
2550
dbainbri4d3a0dc2020-12-02 00:33:42 +00002551 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002553 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002554 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002555
2556 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002558
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002560 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002562 return
2563 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564 pDevEntry.MutexPersOnuConfig.Lock()
2565 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2566 pDevEntry.MutexPersOnuConfig.Unlock()
2567 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002569 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002570 }
mpagenko900ee4b2020-10-12 11:56:34 +00002571}
2572
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002573func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2574 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2575 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002576 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002577 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002578 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002579 OperStatus: voltha.OperStatus_FAILED,
2580 }); err != nil {
2581 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2582 }
2583}
2584
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2586 if devEvent == cmn.OmciAniConfigDone {
2587 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002588 // attention: the device reason update is done based on ONU-UNI-Port related activity
2589 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002591 // 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 +00002592 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302593 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002594 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002595 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2596 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2597 dh.mutexReconcilingFirstPassFlag.Lock()
2598 if dh.reconcilingFirstPass {
2599 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2600 dh.reconcilingFirstPass = false
2601 go dh.ReconcileDeviceFlowConfig(ctx)
2602 }
2603 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002604 }
2605 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002607 // attention: the device reason update is done based on ONU-UNI-Port related activity
2608 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002610 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2611 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002612 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002613 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302614}
2615
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002617 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002618 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302619 // attention: the device reason update is done based on ONU-UNI-Port related activity
2620 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302621
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2623 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002624 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002625 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002626 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002627 }
2628 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002630 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002631 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002632 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302633 }
mpagenkof1fc3862021-02-16 10:09:52 +00002634
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002635 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002636 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002637 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002638 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002639 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002640 }
2641 } else {
2642 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002644 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302645}
2646
praneeth nalmas5a0a5502022-12-23 15:57:00 +05302647// DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302649 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002651 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002652 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002653 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002654 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002655 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002656 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002657 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002659 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002660 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002661 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002663 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002664 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002665 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002667 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002668 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002669 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002670 case cmn.UniEnableStateFailed:
2671 {
2672 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2673 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002674 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002675 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002676 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002677 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002679 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002680 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002681 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002683 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002685 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002686 default:
2687 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002689 }
2690 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002691}
2692
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002694 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002695 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302696 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002697 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002698 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002699 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302700 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002702 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002703 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 +00002704 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002705 //store UniPort with the System-PortNumber key
2706 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002708 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002710 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002711 } //error logging already within UniPort method
2712 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002714 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002715 }
2716 }
2717}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2720 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002721 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002722 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002723 return
2724 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002725 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002726 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002727 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2728 for _, mgmtEntityID := range pptpInstKeys {
2729 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002730 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002731 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2732 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002733 }
2734 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002735 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002736 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002737 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002738 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2739 for _, mgmtEntityID := range veipInstKeys {
2740 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002742 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2743 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002744 }
2745 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002747 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002748 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002749 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2750 for _, mgmtEntityID := range potsInstKeys {
2751 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002753 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2754 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002755 }
2756 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002758 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002759 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002761 return
2762 }
2763
mpagenko2c3f6c52021-11-23 11:22:10 +00002764 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2765 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2766 // 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 -07002767 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2768 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2769 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002770 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2771 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002772 for i := 0; i < int(uniCnt); i++ {
2773 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002774 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002775 }
2776}
2777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002778// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2779func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002780 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302781 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002782 // with following remark:
2783 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2784 // # load on the core
2785
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002786 // 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 +00002787
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002788 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002789 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2791 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2792 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2793 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002794 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002796 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002798 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002799 PortNo: port.PortNo,
2800 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002801 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 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 -04002803 }
2804 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002805 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002806 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002807 }
mpagenko3af1f032020-06-10 08:53:41 +00002808 }
2809 }
2810}
2811
2812// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002813func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2814 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002815 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2816 for uniNo, uniPort := range dh.uniEntityMap {
2817 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002818
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2820 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2821 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2822 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002823 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002824 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002825 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002827 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002828 PortNo: port.PortNo,
2829 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002830 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002831 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 -04002832 }
2833 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002834 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002835 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002836 }
2837
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002838 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002839 }
2840}
2841
2842// ONU_Active/Inactive announcement on system KAFKA bus
2843// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002844func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002845 var de voltha.DeviceEvent
2846 eventContext := make(map[string]string)
2847 //Populating event context
2848 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002849 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002850 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002852 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002853 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 +00002854 }
2855 oltSerialNumber := parentDevice.SerialNumber
2856
2857 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2858 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2859 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302860 eventContext["olt-serial-number"] = oltSerialNumber
2861 eventContext["device-id"] = aDeviceID
2862 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002863 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002864 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2865 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002866 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2867 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2869 deviceEntry.MutexPersOnuConfig.RUnlock()
2870 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002872 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2873 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2874 } else {
2875 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2876 log.Fields{"device-id": aDeviceID})
2877 return
2878 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002879
2880 /* Populating device event body */
2881 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302882 de.ResourceId = aDeviceID
2883 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002884 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2885 de.Description = fmt.Sprintf("%s Event - %s - %s",
2886 cEventObjectType, cOnuActivatedEvent, "Raised")
2887 } else {
2888 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2889 de.Description = fmt.Sprintf("%s Event - %s - %s",
2890 cEventObjectType, cOnuActivatedEvent, "Cleared")
2891 }
2892 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302893 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302895 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002896 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002897 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302898 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002899}
2900
Himani Chawla4d908332020-08-31 12:30:20 +05302901// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002902func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2903 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002904 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302905 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002906 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002907 sFsmName = "LockStateFSM"
2908 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002910 sFsmName = "UnLockStateFSM"
2911 }
mpagenko3af1f032020-06-10 08:53:41 +00002912
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002913 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002914 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002915 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002916 return
2917 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002919 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302920 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002921 dh.pLockStateFsm = pLSFsm
2922 } else {
2923 dh.pUnlockStateFsm = pLSFsm
2924 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002925 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002926 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002928 }
2929}
2930
2931// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002932func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002933 /* Uni Port lock/unlock procedure -
2934 ***** should run via 'adminDone' state and generate the argument requested event *****
2935 */
2936 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302937 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002939 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2940 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002941 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2942 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002943 }
2944 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002946 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2947 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002948 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2949 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002950 }
2951 }
2952 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2954 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002955 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002956 // maybe try a FSM reset and then again ... - TODO!!!
2957 } else {
2958 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002959 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002961 }
2962 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002963 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002965 // maybe try a FSM reset and then again ... - TODO!!!
2966 }
2967 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002969 // maybe try a FSM reset and then again ... - TODO!!!
2970 }
2971}
2972
mpagenko80622a52021-02-09 16:53:23 +00002973// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002974// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002977 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002979 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002980 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002981 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002982 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002984 sFsmName, chUpgradeFsm)
2985 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002987 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2989 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002990 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002991 // maybe try a FSM reset and then again ... - TODO!!!
2992 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2993 }
mpagenko59862f02021-10-11 08:53:18 +00002994 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002995 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2996 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002997 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2998 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002999 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003000 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003001 } else {
3002 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003004 // maybe try a FSM reset and then again ... - TODO!!!
3005 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
3006 }
3007 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003009 // maybe try a FSM reset and then again ... - TODO!!!
3010 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
3011 }
3012 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003014 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3015 }
3016 return nil
3017}
3018
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003019// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3020func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003021 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003023 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003024 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3025 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003026 dh.pLastUpgradeImageState = apImageState
3027 dh.lockUpgradeFsm.Unlock()
3028 //signal upgradeFsm removed using non-blocking channel send
3029 select {
3030 case dh.upgradeFsmChan <- struct{}{}:
3031 default:
3032 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003033 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003034 }
mpagenko80622a52021-02-09 16:53:23 +00003035}
3036
mpagenko15ff4a52021-03-02 10:09:20 +00003037// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3038func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003039 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003040 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003042 return
3043 }
3044
3045 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003046 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003047 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003048 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3049 dh.lockUpgradeFsm.RUnlock()
3050 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3051 return
3052 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003053 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003054 if pUpgradeStatemachine != nil {
3055 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3056 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 UpgradeState := pUpgradeStatemachine.Current()
3058 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3059 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3060 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003061 // 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 +00003062 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003063 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3064 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003065 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003066 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003067 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003068 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3069 dh.upgradeCanceled = true
3070 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3071 }
mpagenko15ff4a52021-03-02 10:09:20 +00003072 return
3073 }
mpagenko59862f02021-10-11 08:53:18 +00003074 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003075 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3076 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003077 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003078 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003079 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3080 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003081 return
3082 }
3083 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003085 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3087 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003088 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3089 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003090 return
3091 }
3092 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003094 }
3095 } else {
3096 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 +00003097 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003098 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3099 dh.upgradeCanceled = true
3100 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3101 }
mpagenko1f8e8822021-06-25 14:10:21 +00003102 }
mpagenko15ff4a52021-03-02 10:09:20 +00003103 return
3104 }
mpagenko59862f02021-10-11 08:53:18 +00003105 dh.lockUpgradeFsm.RUnlock()
3106 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3107 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003108 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3109 dh.upgradeCanceled = true
3110 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3111 }
mpagenko59862f02021-10-11 08:53:18 +00003112 return
3113 }
3114 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3115 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3116 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3117 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3118 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3119 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3120 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003121 }
mpagenko15ff4a52021-03-02 10:09:20 +00003122 }
3123 }
3124 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003126 }
mpagenko59862f02021-10-11 08:53:18 +00003127 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003128}
3129
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303130// SetBackend provides a DB backend for the specified path on the existing KV client
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003131func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003132
3133 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003135 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003136 kvbackend := &db.Backend{
3137 Client: dh.pOpenOnuAc.kvClient,
3138 StoreType: dh.pOpenOnuAc.KVStoreType,
3139 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003140 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003141 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3142 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003143
mpagenkoaf801632020-07-03 10:00:42 +00003144 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003145}
khenaidoo7d3c5582021-08-11 18:09:44 -04003146func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303147 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003148
mpagenkodff5dda2020-08-28 11:52:01 +00003149 for _, field := range flow.GetOfbFields(apFlowItem) {
3150 switch field.Type {
3151 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3152 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003153 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003154 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3155 }
mpagenko01e726e2020-10-23 09:45:29 +00003156 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003157 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3158 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303159 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003160 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303161 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3162 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003163 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3164 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003165 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003166 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303167 return
mpagenkodff5dda2020-08-28 11:52:01 +00003168 }
3169 }
mpagenko01e726e2020-10-23 09:45:29 +00003170 */
mpagenkodff5dda2020-08-28 11:52:01 +00003171 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3172 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303173 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003174 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303175 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003176 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303177 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003178 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303180 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003181 }
3182 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3183 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303184 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303186 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003187 }
3188 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3189 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003191 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3192 }
3193 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3194 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003196 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3197 }
3198 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3199 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003200 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003201 "IPv4-DST": field.GetIpv4Dst()})
3202 }
3203 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3204 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003205 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003206 "IPv4-SRC": field.GetIpv4Src()})
3207 }
3208 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3209 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003210 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003211 "Metadata": field.GetTableMetadata()})
3212 }
3213 /*
3214 default:
3215 {
3216 //all other entires ignored
3217 }
3218 */
3219 }
3220 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303221}
mpagenkodff5dda2020-08-28 11:52:01 +00003222
khenaidoo7d3c5582021-08-11 18:09:44 -04003223func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003224 for _, action := range flow.GetActions(apFlowItem) {
3225 switch action.Type {
3226 /* not used:
3227 case of.OfpActionType_OFPAT_OUTPUT:
3228 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003229 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003230 "Output": action.GetOutput()})
3231 }
3232 */
3233 case of.OfpActionType_OFPAT_PUSH_VLAN:
3234 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003236 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3237 }
3238 case of.OfpActionType_OFPAT_SET_FIELD:
3239 {
3240 pActionSetField := action.GetSetField()
3241 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003243 "OxcmClass": pActionSetField.Field.OxmClass})
3244 }
3245 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303246 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303248 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003249 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303250 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003251 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303252 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003253 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003254 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003255 "Type": pActionSetField.Field.GetOfbField().Type})
3256 }
3257 }
3258 /*
3259 default:
3260 {
3261 //all other entires ignored
3262 }
3263 */
3264 }
3265 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303266}
3267
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303268// addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003269func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003270 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303271 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3272 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303273 var loSetPcp uint8
3274 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303275 var loIPProto uint32
3276 /* the TechProfileId is part of the flow Metadata - compare also comment within
3277 * OLT-Adapter:openolt_flowmgr.go
3278 * Metadata 8 bytes:
3279 * Most Significant 2 Bytes = Inner VLAN
3280 * Next 2 Bytes = Tech Profile ID(TPID)
3281 * Least Significant 4 Bytes = Port ID
3282 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3283 * subscriber related flows.
3284 */
3285
dbainbri4d3a0dc2020-12-02 00:33:42 +00003286 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303287 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003288 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003289 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003290 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303291 }
mpagenko551a4d42020-12-08 18:09:20 +00003292 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003293 loCookie := apFlowItem.GetCookie()
3294 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303295 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003296 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303297 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303298
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303299 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003300 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303301 if loIPProto == 2 {
3302 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3303 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003304 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003305 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303306 return nil
3307 }
mpagenko01e726e2020-10-23 09:45:29 +00003308 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003309 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003310
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303311 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3312 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003313 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003314 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003315 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3316 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3317 //TODO!!: Use DeviceId within the error response to rwCore
3318 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003319 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003320 }
3321 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003322 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003323 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303324 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3325 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3326 loSetVlan = loMatchVlan
3327 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 +00003328 } else {
3329 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3330 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3331 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303332 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003333 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003334 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003335 }
mpagenko9a304ea2020-12-16 15:54:01 +00003336
khenaidoo42dcdfd2021-10-19 17:34:12 -04003337 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003338 if apFlowMetaData != nil {
3339 meter = apFlowMetaData.Meters[0]
3340 }
mpagenkobc4170a2021-08-17 16:42:10 +00003341 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3342 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3343 // when different rules are requested concurrently for the same uni
3344 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3345 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3346 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3348 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003349 //SetUniFlowParams() may block on some rule that is suspended-to-add
3350 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003351 // Also the error is returned to caller via response channel
3352 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303353 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003354 dh.lockVlanConfig.RUnlock()
3355 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003356 return
mpagenkodff5dda2020-08-28 11:52:01 +00003357 }
mpagenkobc4170a2021-08-17 16:42:10 +00003358 dh.lockVlanConfig.RUnlock()
3359 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003360 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303361 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003362 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003363 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003364 if err != nil {
3365 *respChan <- err
3366 }
mpagenko01e726e2020-10-23 09:45:29 +00003367}
3368
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303369// removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003370func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003371 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3372 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3373 //no extra check is done on the rule parameters
3374 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3375 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3376 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3377 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003378 // - 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 +00003379 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003381
3382 /* TT related temporary workaround - should not be needed anymore
3383 for _, field := range flow.GetOfbFields(apFlowItem) {
3384 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3385 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003386 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003387 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3388 if loIPProto == 2 {
3389 // 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 +00003390 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003392 return nil
3393 }
3394 }
3395 } //for all OfbFields
3396 */
3397
mpagenko9a304ea2020-12-16 15:54:01 +00003398 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003399 dh.lockVlanConfig.RLock()
3400 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003401 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3402 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003403 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3404 return
mpagenko01e726e2020-10-23 09:45:29 +00003405 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003406 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003408 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003409 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003410 // Push response on the response channel
3411 if respChan != nil {
3412 // 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
3413 select {
3414 case *respChan <- nil:
3415 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3416 default:
3417 }
3418 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003419 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003420}
3421
Himani Chawla26e555c2020-08-31 12:30:20 +05303422// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003423// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003424// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303426 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003430 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3432 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003433 }
3434
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3436 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303437 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003438 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003439 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3440 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003441 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3442 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003443 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003444 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3445 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003446 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3447 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003449 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303450 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003451 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3453 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003454 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003455 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3457 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003458 }
3459 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003460 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 "device-id": dh.DeviceID})
3462 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003463 }
3464 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003465 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3467 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003468 }
3469 return nil
3470}
3471
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303472// VerifyVlanConfigRequest checks on existence of a given uniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003473// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003474func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003475 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003477 for _, uniPort := range dh.uniEntityMap {
3478 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003480 pCurrentUniPort = uniPort
3481 break //found - end search loop
3482 }
3483 }
3484 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003485 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003487 return
3488 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003490}
3491
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303492// VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003493func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003494 //TODO!! verify and start pending flow configuration
3495 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3496 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003497
3498 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003500 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003501 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003502 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003503 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003504 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003505 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3507 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003508 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003510 } else {
3511 /***** UniVlanConfigFsm continued */
3512 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3514 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003515 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3517 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003518 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003520 } else {
3521 /***** UniVlanConfigFsm continued */
3522 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3524 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003525 }
mpagenkodff5dda2020-08-28 11:52:01 +00003526 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003527 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003528 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3529 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003530 }
3531 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003532 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 +00003533 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3534 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003535 }
3536 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003537 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003539 }
mpagenkof1fc3862021-02-16 10:09:52 +00003540 } else {
3541 dh.lockVlanConfig.RUnlock()
3542 }
mpagenkodff5dda2020-08-28 11:52:01 +00003543}
3544
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303545// RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003546// 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 +00003547func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003548 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003549 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003550 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003551 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003553 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003554}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003555
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303556// startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003557func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003558 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3559 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3560 // obviously then parallel processing on the cancel must be avoided
3561 // deadline context to ensure completion of background routines waited for
3562 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3563 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3564 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003566 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003567 var wg sync.WaitGroup
3568 wg.Add(1) // for the 1 go routine to finish
3569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003570 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003571 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003574}
3575
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303576// StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3577// available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3579 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003580
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003581 if dh.IsReconciling() {
3582 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003583 return nil
3584 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003585 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003586
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003587 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003588 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003589 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3590 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003591 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003592 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003593
mpagenkof1fc3862021-02-16 10:09:52 +00003594 if aWriteToKvStore {
3595 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3596 }
3597 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003598}
3599
dbainbri4d3a0dc2020-12-02 00:33:42 +00003600func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003601 defer cancel() //ensure termination of context (may be pro forma)
3602 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003603 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003604 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003605}
3606
praneeth nalmas5a0a5502022-12-23 15:57:00 +05303607// ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3608//
3609// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
mpagenkoe4782082021-11-25 12:04:26 +00003610func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3611 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3612 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3613 dh.mutexDeviceReason.Lock()
3614 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003615 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003616 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003617 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618 DeviceId: dh.DeviceID,
3619 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003620 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003621 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003622 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003623 return err
3624 }
mpagenkoe4782082021-11-25 12:04:26 +00003625 } else {
3626 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 +00003627 }
mpagenkoe4782082021-11-25 12:04:26 +00003628 dh.deviceReason = deviceReason
3629 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3630 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003631 return nil
3632}
3633
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003634func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3635 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003636 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003637 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3638 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003639 }
mpagenkof1fc3862021-02-16 10:09:52 +00003640 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003641}
3642
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003643// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003644// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003645func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3646 dh.lockDevice.RLock()
3647 defer dh.lockDevice.RUnlock()
3648 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003650 }
3651 return 0, errors.New("error-fetching-uni-port")
3652}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003653
3654// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003655func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3656 var errorsList []error
3657 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 -08003658
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003659 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3660 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3661 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3662
3663 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3664 // successfully.
3665 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3666 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3667 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003668 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 -08003669 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003670 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003671 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003672 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003673}
3674
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003675func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3676 var err error
3677 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003678 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003679
3680 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003682 errorsList = append(errorsList, err)
3683 }
3684 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003685 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003686
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003687 return errorsList
3688}
3689
3690func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3691 var err error
3692 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003693 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003694 // Check if group metric related config is updated
3695 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003696 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3697 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3698 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003699
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003700 if ok && m.Frequency != v.GroupFreq {
3701 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003702 errorsList = append(errorsList, err)
3703 }
3704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705 if ok && m.Enabled != v.Enabled {
3706 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003707 errorsList = append(errorsList, err)
3708 }
3709 }
3710 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003711 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003712 return errorsList
3713}
3714
3715func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3716 var err error
3717 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003718 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003719 // Check if standalone metric related config is updated
3720 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003721 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3722 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3723 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003724
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003725 if ok && m.Frequency != v.SampleFreq {
3726 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003727 errorsList = append(errorsList, err)
3728 }
3729 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003730 if ok && m.Enabled != v.Enabled {
3731 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003732 errorsList = append(errorsList, err)
3733 }
3734 }
3735 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003736 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003737 return errorsList
3738}
3739
3740// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003741func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003742 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003743
3744 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003745 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303746 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003747 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003748 // Initialize the next metric collection time.
3749 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3750 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003751 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003752 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003753 for {
3754 select {
3755 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003756 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003757 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003758 // Stop the L2 PM FSM
3759 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3761 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3762 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003763 }
3764 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003766 }
3767 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003768 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3769 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003770 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003771 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3772 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003773 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003774
Girish Gowdrae09a6202021-01-12 18:10:59 -08003775 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3777 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3778 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3779 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3780 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003781 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003783 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003784 } else {
3785 if dh.pmConfigs.Grouped { // metrics are managed as a group
3786 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003787 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003788
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003789 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3790 // 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 -08003791 // 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 +00003792 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3793 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003794 }
3795 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003796 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3797 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3798 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3799 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003800 }
3801 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003803
3804 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003805 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3806 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3807 // 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 -08003808 // 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 +00003809 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3810 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003811 }
3812 }
3813 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003814 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3815 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3816 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3817 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003818 }
3819 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003820 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003821 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003822 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003823 } */
3824 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003825 }
3826 }
3827}
kesavandfdf77632021-01-26 23:40:33 -05003828
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003830
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003831 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3832 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003833}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003834
Himani Chawla43f95ff2021-06-03 00:24:12 +05303835func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3836 if dh.pOnuMetricsMgr == nil {
3837 return &extension.SingleGetValueResponse{
3838 Response: &extension.GetValueResponse{
3839 Status: extension.GetValueResponse_ERROR,
3840 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3841 },
3842 }
3843 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303844 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303845 return resp
3846}
3847
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003848func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3849
3850 var err error
3851 var pDevOmciCC *cmn.OmciCC
3852 if dh.pOnuOmciDevice == nil {
3853 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3854 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3855 } else {
3856 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3857 if pDevOmciCC == nil {
3858 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3859 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3860 }
3861 }
3862 if err != nil {
3863 return &extension.SingleGetValueResponse{
3864 Response: &extension.GetValueResponse{
3865 Status: extension.GetValueResponse_ERROR,
3866 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3867 },
3868 },
3869 err
3870 }
3871 return pDevOmciCC.GetOmciCounters(), nil
3872}
3873
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3875 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003876 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003877 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003878 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003879}
3880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003881func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003882 var pAdapterFsm *cmn.AdapterFsm
3883 //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 +00003884 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003886 {
mpagenkofbf577d2021-10-12 11:44:33 +00003887 if dh.pOnuOmciDevice != nil {
3888 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3889 } else {
3890 return true //FSM not active - so there is no activity on omci
3891 }
mpagenkof1fc3862021-02-16 10:09:52 +00003892 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003893 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003894 {
mpagenkofbf577d2021-10-12 11:44:33 +00003895 if dh.pOnuOmciDevice != nil {
3896 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3897 } else {
3898 return true //FSM not active - so there is no activity on omci
3899 }
mpagenkof1fc3862021-02-16 10:09:52 +00003900 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003901 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003902 {
mpagenkofbf577d2021-10-12 11:44:33 +00003903 if dh.pLockStateFsm != nil {
3904 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3905 } else {
3906 return true //FSM not active - so there is no activity on omci
3907 }
mpagenkof1fc3862021-02-16 10:09:52 +00003908 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003909 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003910 {
mpagenkofbf577d2021-10-12 11:44:33 +00003911 if dh.pUnlockStateFsm != nil {
3912 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3913 } else {
3914 return true //FSM not active - so there is no activity on omci
3915 }
mpagenkof1fc3862021-02-16 10:09:52 +00003916 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003917 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003918 {
mpagenkofbf577d2021-10-12 11:44:33 +00003919 if dh.pOnuMetricsMgr != nil {
3920 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003921 } else {
3922 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003923 }
3924 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003925 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003926 {
3927 dh.lockUpgradeFsm.RLock()
3928 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003929 if dh.pOnuUpradeFsm != nil {
3930 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3931 } else {
3932 return true //FSM not active - so there is no activity on omci
3933 }
mpagenko80622a52021-02-09 16:53:23 +00003934 }
mpagenkof1fc3862021-02-16 10:09:52 +00003935 default:
3936 {
3937 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003938 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003939 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003940 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003941 }
mpagenkofbf577d2021-10-12 11:44:33 +00003942 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3943 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3944 }
3945 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003946}
3947
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003948func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3949 for _, v := range dh.pOnuTP.PAniConfigFsm {
3950 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003951 return false
3952 }
3953 }
3954 return true
3955}
3956
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003957func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003958 dh.lockVlanConfig.RLock()
3959 defer dh.lockVlanConfig.RUnlock()
3960 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003961 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003962 return false
3963 }
3964 }
3965 return true //FSM not active - so there is no activity on omci
3966}
3967
3968func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3969 dh.lockVlanConfig.RLock()
3970 defer dh.lockVlanConfig.RUnlock()
3971 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003972 if v.PAdaptFsm.PFsm != nil {
3973 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003974 return true //there is at least one VLAN FSM with some active configuration
3975 }
3976 }
3977 }
3978 return false //there is no VLAN FSM with some active configuration
3979}
3980
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003981func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003982 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3983 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3984 return false
3985 }
3986 }
3987 // a further check is done to identify, if at least some data traffic related configuration exists
3988 // 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])
3989 return dh.checkUserServiceExists(ctx)
3990}
3991
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003992func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003993 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3994 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003995 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003996 // TODO: fatal error reset ONU, delete deviceHandler!
3997 return
3998 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003999 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
4000 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004001}
4002
4003func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
4004 dh.mutexCollectorFlag.Lock()
4005 dh.collectorIsRunning = flagValue
4006 dh.mutexCollectorFlag.Unlock()
4007}
4008
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004009func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004010 dh.mutexCollectorFlag.RLock()
4011 flagValue := dh.collectorIsRunning
4012 dh.mutexCollectorFlag.RUnlock()
4013 return flagValue
4014}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304015
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304016func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4017 dh.mutextAlarmManagerFlag.Lock()
4018 dh.alarmManagerIsRunning = flagValue
4019 dh.mutextAlarmManagerFlag.Unlock()
4020}
4021
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004022func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304023 dh.mutextAlarmManagerFlag.RLock()
4024 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004025 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304026 dh.mutextAlarmManagerFlag.RUnlock()
4027 return flagValue
4028}
4029
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004030func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004031 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304032
4033 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004034 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304035 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304036 if stop := <-dh.stopAlarmManager; stop {
4037 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304038 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05304039 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004040 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4041 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304042 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304043 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004044 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4045 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304046 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304047 }
4048}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004049
Girish Gowdrae95687a2021-09-08 16:30:58 -07004050func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4051 dh.mutexFlowMonitoringRoutineFlag.Lock()
4052 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004053 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004054 dh.isFlowMonitoringRoutineActive[uniID] = flag
4055}
4056
4057func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4058 dh.mutexFlowMonitoringRoutineFlag.RLock()
4059 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4060 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004061 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004062 return dh.isFlowMonitoringRoutineActive[uniID]
4063}
4064
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004065func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
4066 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004067
Maninder7961d722021-06-16 22:10:28 +05304068 connectStatus := voltha.ConnectStatus_UNREACHABLE
4069 operState := voltha.OperStatus_UNKNOWN
4070
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004072 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004073 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004074 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004075 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004076 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004077 logger.Debugw(ctx, "reconciling finished signal received",
4078 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4079 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4080 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4081 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4082 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4083 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4084 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4085 // However, a later refactoring of the functionality remains unaffected.
4086 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004087 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004088 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304089 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004090 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304091 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004092 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004093 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304094 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004095 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4096 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304097 operState = voltha.OperStatus_ACTIVE
4098 } else {
4099 operState = voltha.OperStatus_ACTIVATING
4100 }
4101 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004102 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4103 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4104 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304105 operState = voltha.OperStatus_DISCOVERED
4106 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004107 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004108 logger.Debugw(ctx, "Core DeviceStateUpdate",
4109 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304110 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004111 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004113 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004114 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004115 ConnStatus: connectStatus,
4116 OperStatus: operState,
4117 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304118 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004119 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304120 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004121 } else {
Maninderb5187552021-03-23 22:23:42 +05304122 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004123 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004125 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304126 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004127 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004128 } else {
4129 onuDevEntry.MutexPersOnuConfig.RLock()
4130 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4131 connectStatus = voltha.ConnectStatus_REACHABLE
4132 }
4133 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304134 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004135 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004136 }
mpagenko101ac942021-11-16 15:01:29 +00004137 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004138 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004139 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004140 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304141
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004142 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304143 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004144 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004145 } else {
4146 onuDevEntry.MutexPersOnuConfig.RLock()
4147 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4148 connectStatus = voltha.ConnectStatus_REACHABLE
4149 }
4150 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304151 }
4152
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004153 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304154
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004155 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004156 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004157 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004158 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004159 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004160
4161 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4162 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4163 } else {
4164 onuDevEntry.MutexReconciledTpInstances.Lock()
4165 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4166 onuDevEntry.MutexReconciledTpInstances.Unlock()
4167 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004168 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004169 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004170 dh.mutexReconcilingFlag.Lock()
4171 if skipOnuConfig {
4172 dh.reconciling = cSkipOnuConfigReconciling
4173 } else {
4174 dh.reconciling = cOnuConfigReconciling
4175 }
4176 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004177}
4178
mpagenko101ac942021-11-16 15:01:29 +00004179func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4181 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004182 dh.sendChReconcileFinished(success)
4183 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4184 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4185 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004186 } else {
mpagenko101ac942021-11-16 15:01:29 +00004187 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004188 }
4189}
4190
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004192 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004193 defer dh.mutexReconcilingFlag.RUnlock()
4194 return dh.reconciling != cNoReconciling
4195}
4196
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004197func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004198 dh.mutexReconcilingFlag.RLock()
4199 defer dh.mutexReconcilingFlag.RUnlock()
4200 return dh.reconciling == cSkipOnuConfigReconciling
4201}
4202
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004203func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4204 dh.mutexReconcilingFirstPassFlag.Lock()
4205 dh.reconcilingFirstPass = value
4206 dh.mutexReconcilingFirstPassFlag.Unlock()
4207}
4208
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004209func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4210 dh.mutexReconcilingReasonUpdate.Lock()
4211 dh.reconcilingReasonUpdate = value
4212 dh.mutexReconcilingReasonUpdate.Unlock()
4213}
4214
4215func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4216 dh.mutexReconcilingReasonUpdate.RLock()
4217 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4218 return dh.reconcilingReasonUpdate
4219}
4220
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004221func (dh *deviceHandler) getDeviceReason() uint8 {
4222 dh.mutexDeviceReason.RLock()
4223 value := dh.deviceReason
4224 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004225 return value
4226}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004227
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004228func (dh *deviceHandler) GetDeviceReasonString() string {
4229 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004230}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004231
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004232func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004233 dh.mutexReadyForOmciConfig.Lock()
4234 dh.readyForOmciConfig = flagValue
4235 dh.mutexReadyForOmciConfig.Unlock()
4236}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004237func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004238 dh.mutexReadyForOmciConfig.RLock()
4239 flagValue := dh.readyForOmciConfig
4240 dh.mutexReadyForOmciConfig.RUnlock()
4241 return flagValue
4242}
Maninder7961d722021-06-16 22:10:28 +05304243
4244func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004245 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304246 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004247 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304248 }
4249
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004250 logger.Debugw(ctx, "Core DeviceStateUpdate",
4251 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004252 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004253 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004254 ConnStatus: connectStatus,
4255 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4256 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304257 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004258 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304259 }
4260}
khenaidoo7d3c5582021-08-11 18:09:44 -04004261
4262/*
4263Helper functions to communicate with Core
4264*/
4265
4266func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4267 cClient, err := dh.coreClient.GetCoreServiceClient()
4268 if err != nil || cClient == nil {
4269 return nil, err
4270 }
4271 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4272 defer cancel()
4273 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4274 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4275}
4276
khenaidoo42dcdfd2021-10-19 17:34:12 -04004277func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004278 cClient, err := dh.coreClient.GetCoreServiceClient()
4279 if err != nil || cClient == nil {
4280 return err
4281 }
4282 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4283 defer cancel()
4284 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004285 logger.Debugw(subCtx, "device-updated-in-core",
4286 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004287 return err
4288}
4289
4290func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4291 cClient, err := dh.coreClient.GetCoreServiceClient()
4292 if err != nil || cClient == nil {
4293 return err
4294 }
4295 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4296 defer cancel()
4297 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004298 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4299 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004300 return err
4301}
4302
4303func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4304 cClient, err := dh.coreClient.GetCoreServiceClient()
4305 if err != nil || cClient == nil {
4306 return err
4307 }
4308 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4309 defer cancel()
4310 _, err = cClient.DeviceUpdate(subCtx, device)
4311 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4312 return err
4313}
4314
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004315func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004316 cClient, err := dh.coreClient.GetCoreServiceClient()
4317 if err != nil || cClient == nil {
4318 return err
4319 }
4320 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4321 defer cancel()
4322 _, err = cClient.PortCreated(subCtx, port)
4323 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4324 return err
4325}
4326
khenaidoo42dcdfd2021-10-19 17:34:12 -04004327func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004328 cClient, err := dh.coreClient.GetCoreServiceClient()
4329 if err != nil || cClient == nil {
4330 return err
4331 }
4332 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4333 defer cancel()
4334 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004335 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 -04004336 return err
4337}
4338
khenaidoo42dcdfd2021-10-19 17:34:12 -04004339func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004340 cClient, err := dh.coreClient.GetCoreServiceClient()
4341 if err != nil || cClient == nil {
4342 return err
4343 }
4344 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4345 defer cancel()
4346 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004347 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 -04004348 return err
4349}
4350
4351/*
4352Helper functions to communicate with parent adapter
4353*/
4354
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004355func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4356 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4357
4358 var request = ia.TechProfileInstanceRequestMessage{
4359 DeviceId: dh.DeviceID,
4360 TpInstancePath: aTpPath,
4361 ParentDeviceId: dh.parentID,
4362 ParentPonPort: dh.device.ParentPortNo,
4363 OnuId: dh.device.ProxyAddress.OnuId,
4364 UniId: uint32(aUniID),
4365 }
4366
4367 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004368 if err != nil || pgClient == nil {
4369 return nil, err
4370 }
4371 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4372 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004373 logger.Debugw(subCtx, "get-tech-profile-instance",
4374 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004375 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004376}
4377
Girish Gowdrae95687a2021-09-08 16:30:58 -07004378// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4379// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4380func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4381 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4382 dh.setFlowMonitoringIsRunning(uniID, true)
4383 for {
4384 select {
4385 // block on the channel to receive an incoming flow
4386 // process the flow completely before proceeding to handle the next flow
4387 case flowCb := <-dh.flowCbChan[uniID]:
4388 startTime := time.Now()
4389 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4390 respChan := make(chan error)
4391 if flowCb.addFlow {
4392 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4393 } else {
4394 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4395 }
4396 // Block on response and tunnel it back to the caller
4397 *flowCb.respChan <- <-respChan
4398 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4399 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4400 case <-dh.stopFlowMonitoringRoutine[uniID]:
4401 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4402 dh.setFlowMonitoringIsRunning(uniID, false)
4403 return
4404 }
4405 }
4406}
4407
kesavand011d5162021-11-25 19:21:06 +05304408func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4409 request.ParentDeviceId = dh.GetProxyAddressID()
4410 request.ChildDeviceId = dh.DeviceID
4411 request.ProxyAddress = dh.GetProxyAddress()
4412 request.ConnectStatus = common.ConnectStatus_REACHABLE
4413
4414 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4415 if err != nil || pgClient == nil {
4416 return err
4417 }
4418 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4419 defer cancel()
4420 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4421 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4422 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004423 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4424 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304425 }
4426 return err
4427}
4428
khenaidoo42dcdfd2021-10-19 17:34:12 -04004429func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004430 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4431 if err != nil || pgClient == nil {
4432 return err
4433 }
4434 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4435 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004436 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004437 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004438 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4439 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004440 if status.Code(err) == codes.Unavailable {
4441 dh.setOltAvailable(false)
4442 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004443 logger.Errorw(ctx, "omci-failure",
4444 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004445 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004446 }
4447 return err
4448}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004449
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004450func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4451 // Check if there are additional TCONT instances necessary/available
4452 pDevEntry.MutexPersOnuConfig.Lock()
4453 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4454 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4455 pDevEntry.MutexPersOnuConfig.Unlock()
4456 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4457 logger.Debugw(ctx, "checking available TCONT instances",
4458 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4459 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4460 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4461 log.Fields{"device-id": dh.device.Id})
4462 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4463 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4464 }
4465 } else {
4466 pDevEntry.MutexPersOnuConfig.Unlock()
4467 }
4468 // Check if there are enough PrioQueue instances available
4469 if dh.pOnuTP != nil {
4470 var numberOfUsPrioQueueDbInsts int
4471
4472 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4473 for _, mgmtEntityID := range queueInstKeys {
4474 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4475 numberOfUsPrioQueueDbInsts++
4476 }
4477 }
4478 // Check if there is an upstream PriorityQueue instance available for each Gem port
4479 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4480 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4481 log.Fields{"device-id": dh.DeviceID,
4482 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4483 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4484 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4485
4486 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4487 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4488 log.Fields{"device-id": dh.device.Id})
4489 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4490 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4491 }
4492 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4493 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4494 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4495 } else {
4496 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4497 log.Fields{"device-id": dh.DeviceID})
4498 }
4499 return nil
4500}
4501
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004502// GetDeviceID - TODO: add comment
4503func (dh *deviceHandler) GetDeviceID() string {
4504 return dh.DeviceID
4505}
4506
4507// GetProxyAddressID - TODO: add comment
4508func (dh *deviceHandler) GetProxyAddressID() string {
4509 return dh.device.ProxyAddress.GetDeviceId()
4510}
4511
4512// GetProxyAddressType - TODO: add comment
4513func (dh *deviceHandler) GetProxyAddressType() string {
4514 return dh.device.ProxyAddress.GetDeviceType()
4515}
4516
4517// GetProxyAddress - TODO: add comment
4518func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4519 return dh.device.ProxyAddress
4520}
4521
4522// GetEventProxy - TODO: add comment
4523func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4524 return dh.EventProxy
4525}
4526
4527// GetOmciTimeout - TODO: add comment
4528func (dh *deviceHandler) GetOmciTimeout() int {
4529 return dh.pOpenOnuAc.omciTimeout
4530}
4531
4532// GetAlarmAuditInterval - TODO: add comment
4533func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4534 return dh.pOpenOnuAc.alarmAuditInterval
4535}
4536
4537// GetDlToOnuTimeout4M - TODO: add comment
4538func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4539 return dh.pOpenOnuAc.dlToOnuTimeout4M
4540}
4541
4542// GetUniEntityMap - TODO: add comment
4543func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4544 return &dh.uniEntityMap
4545}
4546
4547// GetPonPortNumber - TODO: add comment
4548func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4549 return &dh.ponPortNumber
4550}
4551
4552// GetUniVlanConfigFsm - TODO: add comment
4553func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004554 dh.lockVlanConfig.RLock()
4555 value := dh.UniVlanConfigFsmMap[uniID]
4556 dh.lockVlanConfig.RUnlock()
4557 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004558}
4559
4560// GetOnuAlarmManager - TODO: add comment
4561func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4562 return dh.pAlarmMgr
4563}
4564
4565// GetOnuMetricsManager - TODO: add comment
4566func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4567 return dh.pOnuMetricsMgr
4568}
4569
4570// GetOnuTP - TODO: add comment
4571func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4572 return dh.pOnuTP
4573}
4574
4575// GetBackendPathPrefix - TODO: add comment
4576func (dh *deviceHandler) GetBackendPathPrefix() string {
4577 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4578}
4579
4580// GetOnuIndication - TODO: add comment
4581func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4582 return dh.pOnuIndication
4583}
4584
4585// RLockMutexDeletionInProgressFlag - TODO: add comment
4586func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4587 dh.mutexDeletionInProgressFlag.RLock()
4588}
4589
4590// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4591func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4592 dh.mutexDeletionInProgressFlag.RUnlock()
4593}
4594
4595// GetDeletionInProgress - TODO: add comment
4596func (dh *deviceHandler) GetDeletionInProgress() bool {
4597 return dh.deletionInProgress
4598}
4599
4600// GetPmConfigs - TODO: add comment
4601func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4602 return dh.pmConfigs
4603}
4604
4605// GetDeviceType - TODO: add comment
4606func (dh *deviceHandler) GetDeviceType() string {
4607 return dh.DeviceType
4608}
4609
4610// GetLogicalDeviceID - TODO: add comment
4611func (dh *deviceHandler) GetLogicalDeviceID() string {
4612 return dh.logicalDeviceID
4613}
4614
4615// GetDevice - TODO: add comment
4616func (dh *deviceHandler) GetDevice() *voltha.Device {
4617 return dh.device
4618}
4619
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004620func (dh *deviceHandler) setOltAvailable(value bool) {
4621 dh.mutexOltAvailable.Lock()
4622 dh.oltAvailable = value
4623 dh.mutexOltAvailable.Unlock()
4624}
4625
4626// IsOltAvailable - TODO: add comment
4627func (dh *deviceHandler) IsOltAvailable() bool {
4628 dh.mutexOltAvailable.RLock()
4629 defer dh.mutexOltAvailable.RUnlock()
4630 return dh.oltAvailable
4631}
4632
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004633// GetMetricsEnabled - TODO: add comment
4634func (dh *deviceHandler) GetMetricsEnabled() bool {
4635 return dh.pOpenOnuAc.MetricsEnabled
4636}
4637
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004638// GetExtendedOmciSupportEnabled - TODO: add comment
4639func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4640 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4641}
4642
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004643// InitPmConfigs - TODO: add comment
4644func (dh *deviceHandler) InitPmConfigs() {
4645 dh.pmConfigs = &voltha.PmConfigs{}
4646}
4647
4648// GetUniPortMask - TODO: add comment
4649func (dh *deviceHandler) GetUniPortMask() int {
4650 return dh.pOpenOnuAc.config.UniPortMask
4651}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004652
4653func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4654 tpPathFound := false
4655 for _, tpPath := range aTpPathMap {
4656 if tpPath != "" {
4657 tpPathFound = true
4658 }
4659 }
4660 return tpPathFound
4661}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004662
praneeth nalmas5a0a5502022-12-23 15:57:00 +05304663func (dh *deviceHandler) getOnuActiveAlarms(ctx context.Context) *extension.SingleGetValueResponse {
4664 resp := dh.GetOnuAlarmManager().GetOnuActiveAlarms(ctx)
4665 logger.Debugw(ctx, "Received response from AlarmManager for Active Alarms for DeviceEntry", log.Fields{"device-id": dh.DeviceID})
4666 return resp
4667}
4668
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004669// PrepareForGarbageCollection - remove references to prepare for garbage collection
4670func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4671 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4672
4673 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4674 // first let the objects rest for some time to give all asynchronously started
4675 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004676 time.Sleep(2 * time.Second)
4677
4678 if dh.pOnuOmciDevice != nil {
4679 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4680 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4681 // reset handling (even in future coding), request monitoring is canceled here one last time to
4682 // be sure that all corresponding go routines are terminated
4683 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4684 }
4685 }
4686 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004687
4688 if dh.pOnuTP != nil {
4689 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4690 }
4691 if dh.pOnuMetricsMgr != nil {
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004692 logger.Debugw(ctx, "preparation of garbage collection is done under control of pm fsm - wait for completion",
4693 log.Fields{"device-id": aDeviceID})
Girish Gowdraabcceb12022-04-13 23:35:22 -07004694 select {
4695 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4696 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4697 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4698 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
Holger Hildebrandt34f13b22023-01-18 15:14:59 +00004699 default:
Girish Gowdraabcceb12022-04-13 23:35:22 -07004700 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004701 }
4702 if dh.pAlarmMgr != nil {
4703 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4704 }
4705 if dh.pSelfTestHdlr != nil {
4706 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4707 }
4708 if dh.pLockStateFsm != nil {
4709 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4710 }
4711 if dh.pUnlockStateFsm != nil {
4712 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4713 }
4714 if dh.pOnuUpradeFsm != nil {
4715 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4716 }
4717 if dh.pOnuOmciDevice != nil {
4718 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4719 }
4720 for k, v := range dh.UniVlanConfigFsmMap {
4721 v.PrepareForGarbageCollection(ctx, aDeviceID)
4722 delete(dh.UniVlanConfigFsmMap, k)
4723 }
4724 dh.pOnuOmciDevice = nil
4725 dh.pOnuTP = nil
4726 dh.pOnuMetricsMgr = nil
4727 dh.pAlarmMgr = nil
4728 dh.pSelfTestHdlr = nil
4729 dh.pLockStateFsm = nil
4730 dh.pUnlockStateFsm = nil
4731 dh.pOnuUpradeFsm = nil
4732}