blob: e227543f04a58d031fa5a66da87ae9f34f4658ee [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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package 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
Holger Hildebrandt24d51952020-05-04 14:03:42 +000098//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
99const (
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
Himani Chawla6d2ae152020-09-02 13:11:20 +0530152//deviceHandler will interact with the ONU ? device.
153type 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
Himani Chawla6d2ae152020-09-02 13:11:20 +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
Girish Gowdrae0140f02021-02-02 16:55:09 -0800336//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
mpagenkodff5dda2020-08-28 11:52:01 +0000620//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
Himani Chawla6d2ae152020-09-02 13:11:20 +0530792//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000793//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
795// (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
Himani Chawla6d2ae152020-09-02 13:11:20 +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
1151//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1152// and decrements the according handler wait group waiting for these indications
1153func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1154 waitGroup *cmn.WaitGroupWithTimeOut) {
1155 var reconciledUniVlanConfigEntries []uint8
1156 var appended bool
1157 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1158 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1159 "device-id": dh.DeviceID, "expiry": expiry})
1160 // indicate blocking on channel now to the caller
1161 aSyncChannel <- struct{}{}
1162 for {
1163 select {
1164 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1165 switch uniIndication {
1166 // no activity requested (should normally not be received) - just continue waiting
1167 case cWaitReconcileFlowNoActivity:
1168 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1169 case cWaitReconcileFlowAbortOnError:
1170 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1171 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1172 return
1173 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1174 case cWaitReconcileFlowAbortOnSuccess:
1175 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1176 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1177 return
1178 // this should be a valid UNI vlan config done indication
1179 default:
1180 if uniIndication < platform.MaxUnisPerOnu {
1181 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1182 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1183 if reconciledUniVlanConfigEntries, appended =
1184 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1185 waitGroup.Done()
1186 }
1187 } else {
1188 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1189 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1190 }
1191 } //switch uniIndication
1192
1193 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1194 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1195 log.Fields{"device-id": dh.DeviceID})
1196 return
1197 }
1198 }
1199}
1200
1201func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1202 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1203}
1204
1205func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1206 for _, ele := range slice {
1207 if ele == val {
1208 return slice, false
1209 }
1210 }
1211 return append(slice, val), true
1212}
1213
1214// sendChReconcileFinished - sends true or false on reconcileFinish channel
1215func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1216 if dh != nil { //if the object still exists (might have been already deleted in background)
1217 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1218 select {
1219 case dh.chReconcilingFinished <- success:
1220 default:
1221 }
1222 }
1223}
1224
1225// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1226func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1227 if dh != nil { //if the object still exists (might have been already deleted in background)
1228 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1229 select {
1230 case dh.chUniVlanConfigReconcilingDone <- value:
1231 default:
1232 }
1233 }
1234}
1235
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001238
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001240 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001241 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001243 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001244 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001245
1246 // deadline context to ensure completion of background routines waited for
1247 //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 +05301248 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001249 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001250
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001252
1253 var wg sync.WaitGroup
1254 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001257
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001258 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001260}
1261
mpagenko15ff4a52021-03-02 10:09:20 +00001262//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1263// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001265//was and is called in background - error return does not make sense
1266func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001268 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001270 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001271 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301273 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001275 return
Himani Chawla4d908332020-08-31 12:30:20 +05301276 }
mpagenko01e726e2020-10-23 09:45:29 +00001277
1278 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001280
mpagenko44bd8362021-11-15 11:40:05 +00001281 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001283 // do not set the ConnStatus here as it may conflict with the parallel setting from ONU down indication (updateInterface())
khenaidoo42dcdfd2021-10-19 17:34:12 -04001284 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001286 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001287 OperStatus: voltha.OperStatus_DISCOVERED,
1288 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001289 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001291 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001292 }
mpagenkoe4782082021-11-25 12:04:26 +00001293 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001294 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001295 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001297 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1298 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1299 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1300 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001301}
1302
mpagenkoc8bba412021-01-15 15:38:44 +00001303//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001304// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001305func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001307 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001309
1310 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001312 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1314 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001315 }
1316
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001318 var inactiveImageID uint16
1319 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1320 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001321 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1322 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001323 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001325 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001326 if err == nil {
1327 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1328 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001329 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001330 }
1331 } else {
1332 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001334 }
mpagenko15ff4a52021-03-02 10:09:20 +00001335 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001336 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001338 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1339 dh.upgradeCanceled = true
1340 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1341 }
mpagenko38662d02021-08-11 09:45:19 +00001342 //no effort spent anymore for the old API to automatically cancel and restart the download
1343 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001344 }
mpagenko15ff4a52021-03-02 10:09:20 +00001345 } else {
1346 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001348 }
1349 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1351 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001352 }
1353 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001354}
1355
mpagenkoc26d4c02021-05-06 14:27:57 +00001356//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1357// after the OnuImage has been downloaded to the adapter, called in background
1358func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001360
1361 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001362 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001363 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001365 return
1366 }
1367
1368 var inactiveImageID uint16
1369 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1370 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001372
mpagenko59862f02021-10-11 08:53:18 +00001373 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001375 // but must be still locked at calling createOnuUpgradeFsm
1376 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1377 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1378 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001379 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1380 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001382 //flush the remove upgradeFsmChan channel
1383 select {
1384 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001385 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001387 }
mpagenko59862f02021-10-11 08:53:18 +00001388 dh.lockUpgradeFsm.Unlock()
1389 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1390 dh.upgradeCanceled = true
1391 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1392 }
mpagenko38662d02021-08-11 09:45:19 +00001393 select {
1394 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001396 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1397 return
1398 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001400 }
mpagenko59862f02021-10-11 08:53:18 +00001401 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001402 }
mpagenko38662d02021-08-11 09:45:19 +00001403
1404 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001405 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001406 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001408 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001409 if err == nil {
1410 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1411 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1412 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001414 return
1415 }
mpagenko38662d02021-08-11 09:45:19 +00001416 } else {
1417 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001419 }
1420 return
1421 }
1422 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001424}
1425
1426//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001427func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1428 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 var err error
1430 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1431 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1432 // 2.) activation of the inactive image
1433
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001435 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1437 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001438 }
1439 dh.lockUpgradeFsm.RLock()
1440 if dh.pOnuUpradeFsm != nil {
1441 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001444 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1445 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001446 }
mpagenko59862f02021-10-11 08:53:18 +00001447 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1448 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1449 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1450 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 // use the OnuVendor identification from this device for the internal unique name
1452 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001453 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001454 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001455 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001456 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 "device-id": dh.DeviceID, "error": err})
1458 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 }
mpagenko183647c2021-06-08 15:25:04 +00001460 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001462 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001463 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 } //else
1465 dh.lockUpgradeFsm.RUnlock()
1466
1467 // 2.) check if requested image-version equals the inactive one and start its activation
1468 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1469 var inactiveImageID uint16
1470 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1471 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1473 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001474 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001475 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001477 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001478 if err == nil {
1479 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1480 inactiveImageID, aCommitRequest); err != nil {
1481 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001482 "device-id": dh.DeviceID, "error": err})
1483 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 }
1485 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001487 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001488 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001489 } //else
1490 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 "device-id": dh.DeviceID, "error": err})
1492 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001493}
1494
1495//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001496func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1497 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001498 var err error
1499 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1500 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1501 // 2.) commitment of the active image
1502
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001503 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001504 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001505 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1506 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001507 }
1508 dh.lockUpgradeFsm.RLock()
1509 if dh.pOnuUpradeFsm != nil {
1510 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001511 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001512 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001513 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1514 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001515 }
mpagenko59862f02021-10-11 08:53:18 +00001516 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1517 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1518 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1519 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001520 // use the OnuVendor identification from this device for the internal unique name
1521 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001522 // 1.) check a started upgrade process and relay the commitment request to it
1523 // the running upgrade may be based either on the imageIdentifier (started from download)
1524 // or on the imageVersion (started from pure activation)
1525 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1526 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001527 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "error": err})
1529 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 }
mpagenko183647c2021-06-08 15:25:04 +00001531 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001533 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001534 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001535 } //else
1536 dh.lockUpgradeFsm.RUnlock()
1537
mpagenko183647c2021-06-08 15:25:04 +00001538 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 var activeImageID uint16
1540 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1541 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1543 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001544 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001545 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001547 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001548 if err == nil {
1549 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1550 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001551 "device-id": dh.DeviceID, "error": err})
1552 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001553 }
1554 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001556 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001557 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001558 } //else
1559 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 "device-id": dh.DeviceID, "error": err})
1561 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001562}
1563
mpagenkoaa3afe92021-05-21 16:20:58 +00001564func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001565 aVersion string) *voltha.ImageState {
1566 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001567 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001568 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001569 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001570 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1571 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1572 if aVersion == dh.pLastUpgradeImageState.Version {
1573 pImageState = dh.pLastUpgradeImageState
1574 } else { //state request for an image version different from last processed image version
1575 pImageState = &voltha.ImageState{
1576 Version: aVersion,
1577 //we cannot state something concerning this version
1578 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1579 Reason: voltha.ImageState_NO_ERROR,
1580 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1581 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001582 }
1583 }
mpagenko38662d02021-08-11 09:45:19 +00001584 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001585}
1586
1587func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1588 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001589 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001590 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001591 dh.lockUpgradeFsm.RLock()
1592 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001593 dh.lockUpgradeFsm.RUnlock()
1594 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001595 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001596 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1597 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1598 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1599 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1600 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1601 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001602 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1603 dh.upgradeCanceled = true
1604 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1605 }
mpagenko45586762021-10-01 08:30:22 +00001606 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001607 } else {
mpagenko45586762021-10-01 08:30:22 +00001608 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001609 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1610 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1611 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1612 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1613 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1614 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001615 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1616 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001617 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1618 //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 +00001619 }
1620}
1621
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1623
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001625
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001626 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1629 pDevEntry.MutexOnuImageStatus.Lock()
1630 pDevEntry.POnuImageStatus = onuImageStatus
1631 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001632
1633 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001635 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1636 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001637 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1638 pDevEntry.MutexOnuImageStatus.Lock()
1639 pDevEntry.POnuImageStatus = nil
1640 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001641 return images, err
1642}
1643
Himani Chawla6d2ae152020-09-02 13:11:20 +05301644// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001645// #####################################################################################
1646
1647// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301648// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001651 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1652 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653}
1654
1655// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001658 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659 var err error
1660
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 // populate what we know. rest comes later after mib sync
1662 dh.device.Root = false
1663 dh.device.Vendor = "OpenONU"
1664 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001666 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001669
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 if !dh.IsReconciling() {
1671 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001672 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1673 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1674 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301675 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001676 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001679 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680
Himani Chawla4d908332020-08-31 12:30:20 +05301681 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001682 dh.ponPortNumber = dh.device.ParentPortNo
1683
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1685 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1686 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301689 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001690
1691 /*
1692 self._pon = PonPort.create(self, self._pon_port_number)
1693 self._pon.add_peer(self.parent_id, self._pon_port_number)
1694 self.logger.debug('adding-pon-port-to-agent',
1695 type=self._pon.get_port().type,
1696 admin_state=self._pon.get_port().admin_state,
1697 oper_status=self._pon.get_port().oper_status,
1698 )
1699 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001700 if !dh.IsReconciling() {
1701 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001702 var ponPortNo uint32 = 1
1703 if dh.ponPortNumber != 0 {
1704 ponPortNo = dh.ponPortNumber
1705 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001706
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001707 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001709 PortNo: ponPortNo,
1710 Label: fmt.Sprintf("pon-%d", ponPortNo),
1711 Type: voltha.Port_PON_ONU,
1712 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301713 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001714 PortNo: ponPortNo}}, // Peer port is parent's port number
1715 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001716 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001717 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001718 e.Cancel(err)
1719 return
1720 }
1721 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001722 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001724 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725}
1726
1727// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001728func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001730 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001731 var err error
1732 /*
1733 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1734 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1735 return nil
1736 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001738 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001739 e.Cancel(err)
1740 return
1741 }
1742
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001743 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001745 // reconcilement will be continued after mib download is done
1746 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001747
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001748 /*
1749 ############################################################################
1750 # Setup Alarm handler
1751 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1752 device.serial_number)
1753 ############################################################################
1754 # Setup PM configuration for this device
1755 # Pass in ONU specific options
1756 kwargs = {
1757 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1758 'heartbeat': self.heartbeat,
1759 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1760 }
1761 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1762 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1763 self.logical_device_id, device.serial_number,
1764 grouped=True, freq_override=False, **kwargs)
1765 pm_config = self._pm_metrics.make_proto()
1766 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1767 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1768 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1769
1770 # Note, ONU ID and UNI intf set in add_uni_port method
1771 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1772 ani_ports=[self._pon])
1773
1774 # Code to Run OMCI Test Action
1775 kwargs_omci_test_action = {
1776 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1777 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1778 }
1779 serial_number = device.serial_number
1780 self._test_request = OmciTestRequest(self.core_proxy,
1781 self.omci_agent, self.device_id,
1782 AniG, serial_number,
1783 self.logical_device_id,
1784 exclusive=False,
1785 **kwargs_omci_test_action)
1786
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001787 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001788 else:
1789 self.logger.info('onu-already-activated')
1790 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001791
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001792 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001793}
1794
1795// doStateConnected get the device info and update to voltha core
1796// for comparison of the original method (not that easy to uncomment): compare here:
1797// voltha-openolt-adapter/adaptercore/device_handler.go
1798// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001801 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301802 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001803 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001804 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805}
1806
1807// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001809
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001810 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301811 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001812 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001813 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814
1815 /*
1816 // Synchronous call to update device state - this method is run in its own go routine
1817 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1818 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001819 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 +00001820 return err
1821 }
1822 return nil
1823 */
1824}
1825
1826// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001829 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001830 var err error
1831
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001832 device := dh.device
1833 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 e.Cancel(err)
1837 return
1838 }
1839
1840 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001841 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842 /*
1843 // Update the all ports state on that device to disable
1844 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001845 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001846 return er
1847 }
1848
1849 //Update the device oper state and connection status
1850 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1851 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1852 dh.device = cloned
1853
1854 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001855 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001856 return er
1857 }
1858
1859 //get the child device for the parent device
1860 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1861 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001862 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001863 return err
1864 }
1865 for _, onuDevice := range onuDevices.Items {
1866
1867 // Update onu state as down in onu adapter
1868 onuInd := oop.OnuIndication{}
1869 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001870 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1872 if er != nil {
1873 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001874 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001875 //Do not return here and continue to process other ONUs
1876 }
1877 }
1878 // * Discovered ONUs entries need to be cleared , since after OLT
1879 // is up, it starts sending discovery indications again* /
1880 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001881 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001882 return nil
1883 */
Himani Chawla4d908332020-08-31 12:30:20 +05301884 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001886 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001887}
1888
Himani Chawla6d2ae152020-09-02 13:11:20 +05301889// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001890// #################################################################################
1891
1892// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301893// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001894
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001895//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1896func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001897 dh.lockDevice.RLock()
1898 pOnuDeviceEntry := dh.pOnuOmciDevice
1899 if aWait && pOnuDeviceEntry == nil {
1900 //keep the read sema short to allow for subsequent write
1901 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001902 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001903 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1904 // so it might be needed to wait here for that event with some timeout
1905 select {
1906 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001908 return nil
1909 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001910 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001911 // if written now, we can return the written value without sema
1912 return dh.pOnuOmciDevice
1913 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001914 }
mpagenko3af1f032020-06-10 08:53:41 +00001915 dh.lockDevice.RUnlock()
1916 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001917}
1918
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001919//setDeviceHandlerEntries sets the ONU device entry within the handler
1920func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1921 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922 dh.lockDevice.Lock()
1923 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001924 dh.pOnuOmciDevice = apDeviceEntry
1925 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001926 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301927 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001928 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001929}
1930
Himani Chawla6d2ae152020-09-02 13:11:20 +05301931//addOnuDeviceEntry creates a new ONU device or returns the existing
1932func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001933 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001934
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001936 if deviceEntry == nil {
1937 /* costum_me_map in python code seems always to be None,
1938 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1939 /* also no 'clock' argument - usage open ...*/
1940 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1942 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1943 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1944 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1945 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001946 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001948 // fire deviceEntry ready event to spread to possibly waiting processing
1949 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001951 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001953 }
1954 // might be updated with some error handling !!!
1955 return nil
1956}
1957
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001959 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001960 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1961
1962 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001963
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001965 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001966 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1967 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001968 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 if !dh.IsReconciling() {
1970 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001973 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001976
khenaidoo42dcdfd2021-10-19 17:34:12 -04001977 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001978 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001979 OperStatus: voltha.OperStatus_ACTIVATING,
1980 ConnStatus: voltha.ConnectStatus_REACHABLE,
1981 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001982 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001984 }
1985 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001987 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001988
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001989 pDevEntry.MutexPersOnuConfig.RLock()
1990 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1991 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 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 +00001993 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001994 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001995 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001996 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001997 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001998 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001999 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
2000 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
2001 // 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 +00002002 // 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 +00002003 // so let's just try to keep it simple ...
2004 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002006 if err != nil || device == nil {
2007 //TODO: needs to handle error scenarios
2008 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2009 return errors.New("Voltha Device not found")
2010 }
2011 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002012
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002013 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002014 return err
mpagenko3af1f032020-06-10 08:53:41 +00002015 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002016 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002017
2018 /* this might be a good time for Omci Verify message? */
2019 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002020 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002021 dh.device.Id, pDevEntry.PDevOmciCC, false,
mpagenko900ee4b2020-10-12 11:56:34 +00002022 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002023 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002024
2025 /* give the handler some time here to wait for the OMCi verification result
2026 after Timeout start and try MibUpload FSM anyway
2027 (to prevent stopping on just not supported OMCI verification from ONU) */
2028 select {
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002029 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002030 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002031 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002032 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002033 }
2034
2035 /* In py code it looks earlier (on activate ..)
2036 # Code to Run OMCI Test Action
2037 kwargs_omci_test_action = {
2038 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2039 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2040 }
2041 serial_number = device.serial_number
2042 self._test_request = OmciTestRequest(self.core_proxy,
2043 self.omci_agent, self.device_id,
2044 AniG, serial_number,
2045 self.logical_device_id,
2046 exclusive=False,
2047 **kwargs_omci_test_action)
2048 ...
2049 # Start test requests after a brief pause
2050 if not self._test_request_started:
2051 self._test_request_started = True
2052 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2053 reactor.callLater(tststart, self._test_request.start_collector)
2054
2055 */
2056 /* which is then: in omci_test_request.py : */
2057 /*
2058 def start_collector(self, callback=None):
2059 """
2060 Start the collection loop for an adapter if the frequency > 0
2061
2062 :param callback: (callable) Function to call to collect PM data
2063 """
2064 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2065 if callback is None:
2066 callback = self.perform_test_omci
2067
2068 if self.lc is None:
2069 self.lc = LoopingCall(callback)
2070
2071 if self.default_freq > 0:
2072 self.lc.start(interval=self.default_freq / 10)
2073
2074 def perform_test_omci(self):
2075 """
2076 Perform the initial test request
2077 """
2078 ani_g_entities = self._device.configuration.ani_g_entities
2079 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2080 is not None else None
2081 self._entity_id = ani_g_entities_ids[0]
2082 self.logger.info('perform-test', entity_class=self._entity_class,
2083 entity_id=self._entity_id)
2084 try:
2085 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2086 result = yield self._device.omci_cc.send(frame)
2087 if not result.fields['omci_message'].fields['success_code']:
2088 self.logger.info('Self-Test Submitted Successfully',
2089 code=result.fields[
2090 'omci_message'].fields['success_code'])
2091 else:
2092 raise TestFailure('Test Failure: {}'.format(
2093 result.fields['omci_message'].fields['success_code']))
2094 except TimeoutError as e:
2095 self.deferred.errback(failure.Failure(e))
2096
2097 except Exception as e:
2098 self.logger.exception('perform-test-Error', e=e,
2099 class_id=self._entity_class,
2100 entity_id=self._entity_id)
2101 self.deferred.errback(failure.Failure(e))
2102
2103 */
2104
2105 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002106 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002107
mpagenko1cc3cb42020-07-27 15:24:38 +00002108 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2109 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2110 * 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 +05302111 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002112 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002113 //call MibUploadFSM - transition up to state UlStInSync
2114 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002115 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002116 if pMibUlFsm.Is(mib.UlStDisabled) {
2117 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2118 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2119 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302120 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002121 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302122 //Determine ONU status and start/re-start MIB Synchronization tasks
2123 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002124 if pDevEntry.IsNewOnu() {
2125 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2126 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2127 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002128 }
Himani Chawla4d908332020-08-31 12:30:20 +05302129 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002130 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2131 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2132 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302133 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002134 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002135 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002136 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002138 "device-id": dh.DeviceID})
2139 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002140 }
2141 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002142 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2143 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002144 }
2145 return nil
2146}
2147
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002148func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002149 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002150 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002151 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2152 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002153
mpagenko900ee4b2020-10-12 11:56:34 +00002154 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2155 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2156 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002157 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002160 // abort: system behavior is just unstable ...
2161 return err
2162 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002163 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 _ = 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 +00002165
2166 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002167 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002168 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002169 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002170 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2171 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002172 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002174
2175 //TODO!!! remove existing traffic profiles
2176 /* from py code, if TP's exist, remove them - not yet implemented
2177 self._tp = dict()
2178 # Let TP download happen again
2179 for uni_id in self._tp_service_specific_task:
2180 self._tp_service_specific_task[uni_id].clear()
2181 for uni_id in self._tech_profile_download_done:
2182 self._tech_profile_download_done[uni_id].clear()
2183 */
2184
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002186
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002187 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002188
mpagenkoe4782082021-11-25 12:04:26 +00002189 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002190 // abort: system behavior is just unstable ...
2191 return err
2192 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002194 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002195 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002197 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2198 OperStatus: voltha.OperStatus_DISCOVERED,
2199 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002200 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002203 // abort: system behavior is just unstable ...
2204 return err
2205 }
2206 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002208 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002209 return nil
2210}
2211
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002212func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002213 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2214 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2215 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2216 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002217 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002218
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002220 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002221 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2222 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002223 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002224 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002225 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002226 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002227 pDevEntry.MutexOnuImageStatus.RLock()
2228 if pDevEntry.POnuImageStatus != nil {
2229 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002230 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002232
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002233 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002234 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002235 }
2236 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002237 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002238 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002239 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002240 }
mpagenko101ac942021-11-16 15:01:29 +00002241 //stop any deviceHandler reconcile processing (if running)
2242 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002243 //port lock/unlock FSM's may be active
2244 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002245 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002246 }
2247 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002249 }
2250 //techProfile related PonAniConfigFsm FSM may be active
2251 if dh.pOnuTP != nil {
2252 // should always be the case here
2253 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002254 if dh.pOnuTP.PAniConfigFsm != nil {
2255 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2256 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002257 }
mpagenko900ee4b2020-10-12 11:56:34 +00002258 }
2259 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002260 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002261 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002263 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002264 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002265 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002266 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002267 } else {
2268 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002269 }
2270 }
2271 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002272 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002273 // Stop collector routine
2274 dh.stopCollector <- true
2275 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002276 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302277 dh.stopAlarmManager <- true
2278 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002279 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002280 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002281 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302282
Girish Gowdrae95687a2021-09-08 16:30:58 -07002283 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2284
mpagenko80622a52021-02-09 16:53:23 +00002285 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002287 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002288 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002290 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002291 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002292 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2293 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2294 // (even though it may also run into direct cancellation, a bit hard to verify here)
2295 // so don't set 'dh.upgradeCanceled = true' here!
2296 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2297 }
mpagenko38662d02021-08-11 09:45:19 +00002298 }
mpagenko80622a52021-02-09 16:53:23 +00002299
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002301 return nil
2302}
2303
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002304func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2305 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 +05302306
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002307 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002308 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002309 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002311 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002312 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002314
mpagenkoa40e99a2020-11-17 13:50:39 +00002315 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2316 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2317 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2318 * disable/enable toggling here to allow traffic
2319 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2320 * like the py comment says:
2321 * # start by locking all the unis till mib sync and initial mib is downloaded
2322 * # this way we can capture the port down/up events when we are ready
2323 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302324
mpagenkoa40e99a2020-11-17 13:50:39 +00002325 // Init Uni Ports to Admin locked state
2326 // *** should generate UniLockStateDone event *****
2327 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002329 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002332 }
2333}
2334
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2336 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302337 /* Mib download procedure -
2338 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2339 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002341 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002343 return
2344 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002345 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302346 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002347 if pMibDlFsm.Is(mib.DlStDisabled) {
2348 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2349 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 +05302350 // maybe try a FSM reset and then again ... - TODO!!!
2351 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002352 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302353 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2355 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002357 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302358 //Begin MIB data download (running autonomously)
2359 }
2360 }
2361 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302364 // maybe try a FSM reset and then again ... - TODO!!!
2365 }
2366 /***** Mib download started */
2367 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302369 }
2370}
2371
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002372func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2373 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002374 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2375 if pDevEntry == nil {
2376 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2377 return
2378 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002380 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002381 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002382 // update device info in core
2383 pDevEntry.MutexPersOnuConfig.RLock()
2384 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2385 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2386 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2387 pDevEntry.MutexPersOnuConfig.RUnlock()
2388 dh.logicalDeviceID = dh.DeviceID
2389 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2390 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2391 }
2392 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002393 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2394 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2395 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2396 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002397 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002399 ConnStatus: voltha.ConnectStatus_REACHABLE,
2400 OperStatus: voltha.OperStatus_ACTIVE,
2401 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302402 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302404 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002405 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302406 }
2407 } else {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002408 logger.Debugw(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302410 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002411 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002412
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002413 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002414 var waitForOmciProcessor sync.WaitGroup
2415 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002416 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002417 go dh.StartCollector(ctx, &waitForOmciProcessor)
2418 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002419 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 if !dh.GetAlarmManagerIsRunning(ctx) {
2421 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002422 }
2423
Girish Gowdrae95687a2021-09-08 16:30:58 -07002424 // Start flow handler routines per UNI
2425 for _, uniPort := range dh.uniEntityMap {
2426 // only if this port was enabled for use by the operator at startup
2427 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2428 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2429 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2430 }
2431 }
2432 }
2433
Girish Gowdrae0140f02021-02-02 16:55:09 -08002434 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002435 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002436 // There is no way we should be landing here, but if we do then
2437 // there is nothing much we can do about this other than log error
2438 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2439 }
2440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002441 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 pDevEntry.MutexPersOnuConfig.RLock()
2444 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2445 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002446 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002448 dh.mutexForDisableDeviceRequested.Lock()
2449 dh.disableDeviceRequested = true
2450 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002451 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002452 // reconcilement will be continued after ani config is done
2453 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002455 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002456 dh.mutexForDisableDeviceRequested.RLock()
2457 if !dh.disableDeviceRequested {
2458 if dh.pUnlockStateFsm == nil {
2459 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2460 } else { //UnlockStateFSM already init
2461 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2462 dh.runUniLockFsm(ctx, false)
2463 }
2464 dh.mutexForDisableDeviceRequested.RUnlock()
2465 } else {
2466 dh.mutexForDisableDeviceRequested.RUnlock()
2467 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002468 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302469 }
2470}
2471
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2473 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302474
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 if !dh.IsReconciling() {
2476 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002477 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2479 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002480 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002482 return
2483 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 pDevEntry.MutexPersOnuConfig.Lock()
2485 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2486 pDevEntry.MutexPersOnuConfig.Unlock()
2487 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002489 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002490 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302491 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 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 +00002493 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002494 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002495 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302496 }
2497}
2498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002500 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002501 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002502
mpagenko44bd8362021-11-15 11:40:05 +00002503 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002504 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002506 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002507 OperStatus: voltha.OperStatus_UNKNOWN,
2508 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002509 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002511 }
2512
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002513 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002514 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002515 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002516
2517 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002521 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002523 return
2524 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 pDevEntry.MutexPersOnuConfig.Lock()
2526 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2527 pDevEntry.MutexPersOnuConfig.Unlock()
2528 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002531 }
mpagenko900ee4b2020-10-12 11:56:34 +00002532}
2533
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002535 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002537 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002539 ConnStatus: voltha.ConnectStatus_REACHABLE,
2540 OperStatus: voltha.OperStatus_ACTIVE,
2541 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002542 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002543 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002544 }
2545
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002548 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002549 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002550
2551 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002553
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002555 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002557 return
2558 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 pDevEntry.MutexPersOnuConfig.Lock()
2560 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2561 pDevEntry.MutexPersOnuConfig.Unlock()
2562 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002563 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002565 }
mpagenko900ee4b2020-10-12 11:56:34 +00002566}
2567
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002568func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2569 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2570 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002571 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002572 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002573 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002574 OperStatus: voltha.OperStatus_FAILED,
2575 }); err != nil {
2576 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2577 }
2578}
2579
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2581 if devEvent == cmn.OmciAniConfigDone {
2582 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002583 // attention: the device reason update is done based on ONU-UNI-Port related activity
2584 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002586 // 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 +00002587 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302588 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002590 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2591 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2592 dh.mutexReconcilingFirstPassFlag.Lock()
2593 if dh.reconcilingFirstPass {
2594 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2595 dh.reconcilingFirstPass = false
2596 go dh.ReconcileDeviceFlowConfig(ctx)
2597 }
2598 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002599 }
2600 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002601 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002602 // attention: the device reason update is done based on ONU-UNI-Port related activity
2603 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002605 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2606 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002607 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002608 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302609}
2610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002613 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302614 // attention: the device reason update is done based on ONU-UNI-Port related activity
2615 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302616
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2618 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002619 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002620 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002621 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002622 }
2623 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002624 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002625 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002626 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002627 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302628 }
mpagenkof1fc3862021-02-16 10:09:52 +00002629
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002631 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002632 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002633 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002635 }
2636 } else {
2637 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002638 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002639 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302640}
2641
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002642//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2643func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302644 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002645 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002646 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002647 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002648 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002650 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002652 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002653 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002654 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002655 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002656 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002657 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002658 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002660 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002661 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002662 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002663 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002664 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002665 case cmn.UniEnableStateFailed:
2666 {
2667 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2668 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002670 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002671 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002672 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002674 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002675 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002676 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002678 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002679 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002680 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002681 default:
2682 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002684 }
2685 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002686}
2687
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002689 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002690 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302691 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002692 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002693 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002694 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302695 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002696 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002697 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002698 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 +00002699 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002700 //store UniPort with the System-PortNumber key
2701 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002703 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002705 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002706 } //error logging already within UniPort method
2707 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002709 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002710 }
2711 }
2712}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002713
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2715 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002716 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002717 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002718 return
2719 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002720 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002721 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002722 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2723 for _, mgmtEntityID := range pptpInstKeys {
2724 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002726 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2727 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002728 }
2729 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002730 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002731 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002733 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2734 for _, mgmtEntityID := range veipInstKeys {
2735 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002737 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2738 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002739 }
2740 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002742 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002743 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002744 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2745 for _, mgmtEntityID := range potsInstKeys {
2746 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002748 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2749 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002750 }
2751 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002753 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002754 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002755 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002756 return
2757 }
2758
mpagenko2c3f6c52021-11-23 11:22:10 +00002759 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2760 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2761 // 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 -07002762 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2763 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2764 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002765 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2766 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002767 for i := 0; i < int(uniCnt); i++ {
2768 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002769 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002770 }
2771}
2772
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2774func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002775 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302776 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002777 // with following remark:
2778 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2779 // # load on the core
2780
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002781 // 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 +00002782
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002783 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002784 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002785 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2786 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2787 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2788 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002789 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002791 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002792 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002793 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 PortNo: port.PortNo,
2795 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002796 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002797 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 -04002798 }
2799 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002800 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002802 }
mpagenko3af1f032020-06-10 08:53:41 +00002803 }
2804 }
2805}
2806
2807// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2809 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002810 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2811 for uniNo, uniPort := range dh.uniEntityMap {
2812 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002813
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002814 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2815 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2816 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2817 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002818 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002820 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002822 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002823 PortNo: port.PortNo,
2824 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002825 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826 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 -04002827 }
2828 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002829 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002830 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002831 }
2832
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002833 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002834 }
2835}
2836
2837// ONU_Active/Inactive announcement on system KAFKA bus
2838// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002840 var de voltha.DeviceEvent
2841 eventContext := make(map[string]string)
2842 //Populating event context
2843 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002844 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002845 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002846 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002847 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002848 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 +00002849 }
2850 oltSerialNumber := parentDevice.SerialNumber
2851
2852 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2853 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2854 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302855 eventContext["olt-serial-number"] = oltSerialNumber
2856 eventContext["device-id"] = aDeviceID
2857 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002858 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2860 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002861 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2862 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002863 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2864 deviceEntry.MutexPersOnuConfig.RUnlock()
2865 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002867 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2868 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2869 } else {
2870 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2871 log.Fields{"device-id": aDeviceID})
2872 return
2873 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002874
2875 /* Populating device event body */
2876 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302877 de.ResourceId = aDeviceID
2878 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002879 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2880 de.Description = fmt.Sprintf("%s Event - %s - %s",
2881 cEventObjectType, cOnuActivatedEvent, "Raised")
2882 } else {
2883 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2884 de.Description = fmt.Sprintf("%s Event - %s - %s",
2885 cEventObjectType, cOnuActivatedEvent, "Cleared")
2886 }
2887 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302888 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302890 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002891 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002892 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302893 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002894}
2895
Himani Chawla4d908332020-08-31 12:30:20 +05302896// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2898 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002899 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302900 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002901 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002902 sFsmName = "LockStateFSM"
2903 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002905 sFsmName = "UnLockStateFSM"
2906 }
mpagenko3af1f032020-06-10 08:53:41 +00002907
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002909 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002911 return
2912 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002913 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002914 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302915 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002916 dh.pLockStateFsm = pLSFsm
2917 } else {
2918 dh.pUnlockStateFsm = pLSFsm
2919 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002921 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002923 }
2924}
2925
2926// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002928 /* Uni Port lock/unlock procedure -
2929 ***** should run via 'adminDone' state and generate the argument requested event *****
2930 */
2931 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302932 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002933 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002934 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2935 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2937 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002938 }
2939 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002941 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2942 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2944 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002945 }
2946 }
2947 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002948 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2949 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002950 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002951 // maybe try a FSM reset and then again ... - TODO!!!
2952 } else {
2953 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002954 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002956 }
2957 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002960 // maybe try a FSM reset and then again ... - TODO!!!
2961 }
2962 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002964 // maybe try a FSM reset and then again ... - TODO!!!
2965 }
2966}
2967
mpagenko80622a52021-02-09 16:53:23 +00002968// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002969// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002972 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002974 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002976 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002977 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002979 sFsmName, chUpgradeFsm)
2980 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002982 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002983 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2984 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002985 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002986 // maybe try a FSM reset and then again ... - TODO!!!
2987 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2988 }
mpagenko59862f02021-10-11 08:53:18 +00002989 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002990 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2991 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002992 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2993 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002994 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002995 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002996 } else {
2997 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002999 // maybe try a FSM reset and then again ... - TODO!!!
3000 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
3001 }
3002 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"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 internal FSM could not be created for device-id: %s", dh.device.Id))
3006 }
3007 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003009 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3010 }
3011 return nil
3012}
3013
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3015func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003016 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003018 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003019 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3020 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003021 dh.pLastUpgradeImageState = apImageState
3022 dh.lockUpgradeFsm.Unlock()
3023 //signal upgradeFsm removed using non-blocking channel send
3024 select {
3025 case dh.upgradeFsmChan <- struct{}{}:
3026 default:
3027 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003028 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003029 }
mpagenko80622a52021-02-09 16:53:23 +00003030}
3031
mpagenko15ff4a52021-03-02 10:09:20 +00003032// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3033func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003035 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003037 return
3038 }
3039
3040 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003041 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003042 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003043 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3044 dh.lockUpgradeFsm.RUnlock()
3045 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3046 return
3047 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003048 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003049 if pUpgradeStatemachine != nil {
3050 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3051 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003052 UpgradeState := pUpgradeStatemachine.Current()
3053 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3054 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3055 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003056 // 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 +00003057 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003058 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3059 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003060 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003061 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003063 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3064 dh.upgradeCanceled = true
3065 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3066 }
mpagenko15ff4a52021-03-02 10:09:20 +00003067 return
3068 }
mpagenko59862f02021-10-11 08:53:18 +00003069 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003070 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3071 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003072 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003073 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003074 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3075 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003076 return
3077 }
3078 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003079 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003080 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3082 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003083 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3084 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003085 return
3086 }
3087 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003088 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003089 }
3090 } else {
3091 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 +00003092 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003093 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3094 dh.upgradeCanceled = true
3095 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3096 }
mpagenko1f8e8822021-06-25 14:10:21 +00003097 }
mpagenko15ff4a52021-03-02 10:09:20 +00003098 return
3099 }
mpagenko59862f02021-10-11 08:53:18 +00003100 dh.lockUpgradeFsm.RUnlock()
3101 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3102 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003103 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3104 dh.upgradeCanceled = true
3105 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3106 }
mpagenko59862f02021-10-11 08:53:18 +00003107 return
3108 }
3109 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3110 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3111 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3112 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3113 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3114 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3115 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003116 }
mpagenko15ff4a52021-03-02 10:09:20 +00003117 }
3118 }
3119 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003121 }
mpagenko59862f02021-10-11 08:53:18 +00003122 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003123}
3124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125//SetBackend provides a DB backend for the specified path on the existing KV client
3126func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003127
3128 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003130 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003131 kvbackend := &db.Backend{
3132 Client: dh.pOpenOnuAc.kvClient,
3133 StoreType: dh.pOpenOnuAc.KVStoreType,
3134 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003135 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003136 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3137 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003138
mpagenkoaf801632020-07-03 10:00:42 +00003139 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003140}
khenaidoo7d3c5582021-08-11 18:09:44 -04003141func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303142 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003143
mpagenkodff5dda2020-08-28 11:52:01 +00003144 for _, field := range flow.GetOfbFields(apFlowItem) {
3145 switch field.Type {
3146 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3147 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003149 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3150 }
mpagenko01e726e2020-10-23 09:45:29 +00003151 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003152 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3153 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303154 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003155 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303156 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3157 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003158 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3159 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003160 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003161 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303162 return
mpagenkodff5dda2020-08-28 11:52:01 +00003163 }
3164 }
mpagenko01e726e2020-10-23 09:45:29 +00003165 */
mpagenkodff5dda2020-08-28 11:52:01 +00003166 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3167 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303168 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003169 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303170 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003171 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303172 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003173 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303175 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003176 }
3177 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3178 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303179 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303181 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003182 }
3183 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3184 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003186 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3187 }
3188 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
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-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3192 }
3193 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
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 "IPv4-DST": field.GetIpv4Dst()})
3197 }
3198 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
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-SRC": field.GetIpv4Src()})
3202 }
3203 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
3207 }
3208 /*
3209 default:
3210 {
3211 //all other entires ignored
3212 }
3213 */
3214 }
3215 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303216}
mpagenkodff5dda2020-08-28 11:52:01 +00003217
khenaidoo7d3c5582021-08-11 18:09:44 -04003218func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003219 for _, action := range flow.GetActions(apFlowItem) {
3220 switch action.Type {
3221 /* not used:
3222 case of.OfpActionType_OFPAT_OUTPUT:
3223 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003224 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003225 "Output": action.GetOutput()})
3226 }
3227 */
3228 case of.OfpActionType_OFPAT_PUSH_VLAN:
3229 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003230 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003231 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3232 }
3233 case of.OfpActionType_OFPAT_SET_FIELD:
3234 {
3235 pActionSetField := action.GetSetField()
3236 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003238 "OxcmClass": pActionSetField.Field.OxmClass})
3239 }
3240 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303241 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303243 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003244 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303245 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303247 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003248 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003249 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003250 "Type": pActionSetField.Field.GetOfbField().Type})
3251 }
3252 }
3253 /*
3254 default:
3255 {
3256 //all other entires ignored
3257 }
3258 */
3259 }
3260 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303261}
3262
3263//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003264func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003265 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303266 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3267 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303268 var loSetPcp uint8
3269 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303270 var loIPProto uint32
3271 /* the TechProfileId is part of the flow Metadata - compare also comment within
3272 * OLT-Adapter:openolt_flowmgr.go
3273 * Metadata 8 bytes:
3274 * Most Significant 2 Bytes = Inner VLAN
3275 * Next 2 Bytes = Tech Profile ID(TPID)
3276 * Least Significant 4 Bytes = Port ID
3277 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3278 * subscriber related flows.
3279 */
3280
dbainbri4d3a0dc2020-12-02 00:33:42 +00003281 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303282 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003283 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003284 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003285 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303286 }
mpagenko551a4d42020-12-08 18:09:20 +00003287 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003288 loCookie := apFlowItem.GetCookie()
3289 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303290 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003291 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303292 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303293
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303294 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003295 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303296 if loIPProto == 2 {
3297 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3298 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003299 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003300 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303301 return nil
3302 }
mpagenko01e726e2020-10-23 09:45:29 +00003303 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003304 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003305
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303306 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3307 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003308 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003309 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003310 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3311 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3312 //TODO!!: Use DeviceId within the error response to rwCore
3313 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003314 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003315 }
3316 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003317 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003318 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303319 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3320 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3321 loSetVlan = loMatchVlan
3322 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 +00003323 } else {
3324 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3325 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3326 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303327 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003328 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003329 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003330 }
mpagenko9a304ea2020-12-16 15:54:01 +00003331
khenaidoo42dcdfd2021-10-19 17:34:12 -04003332 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003333 if apFlowMetaData != nil {
3334 meter = apFlowMetaData.Meters[0]
3335 }
mpagenkobc4170a2021-08-17 16:42:10 +00003336 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3337 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3338 // when different rules are requested concurrently for the same uni
3339 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3340 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3341 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003342 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3343 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003344 //SetUniFlowParams() may block on some rule that is suspended-to-add
3345 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003346 // Also the error is returned to caller via response channel
3347 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303348 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003349 dh.lockVlanConfig.RUnlock()
3350 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003351 return
mpagenkodff5dda2020-08-28 11:52:01 +00003352 }
mpagenkobc4170a2021-08-17 16:42:10 +00003353 dh.lockVlanConfig.RUnlock()
3354 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003355 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303356 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003357 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003358 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003359 if err != nil {
3360 *respChan <- err
3361 }
mpagenko01e726e2020-10-23 09:45:29 +00003362}
3363
3364//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003365func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003366 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3367 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3368 //no extra check is done on the rule parameters
3369 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3370 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3371 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3372 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003373 // - 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 +00003374 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003375 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003376
3377 /* TT related temporary workaround - should not be needed anymore
3378 for _, field := range flow.GetOfbFields(apFlowItem) {
3379 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3380 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003381 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003382 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3383 if loIPProto == 2 {
3384 // 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 +00003385 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003386 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003387 return nil
3388 }
3389 }
3390 } //for all OfbFields
3391 */
3392
mpagenko9a304ea2020-12-16 15:54:01 +00003393 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003394 dh.lockVlanConfig.RLock()
3395 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003396 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3397 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003398 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3399 return
mpagenko01e726e2020-10-23 09:45:29 +00003400 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003401 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003403 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003404 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003405 // Push response on the response channel
3406 if respChan != nil {
3407 // 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
3408 select {
3409 case *respChan <- nil:
3410 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3411 default:
3412 }
3413 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003414 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003415}
3416
Himani Chawla26e555c2020-08-31 12:30:20 +05303417// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003418// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003419// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003420func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303421 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 +00003422 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003423
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003425 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003426 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3427 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003428 }
3429
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003430 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3431 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303432 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003433 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003434 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3435 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003436 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3437 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003438 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3440 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003441 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3442 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003443 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003444 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303445 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003446 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003447 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3448 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003449 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003450 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003451 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3452 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003453 }
3454 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003455 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 "device-id": dh.DeviceID})
3457 return fmt.Errorf("uniVlanConfigFsm invalid 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 could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3462 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003463 }
3464 return nil
3465}
3466
mpagenkofc4f56e2020-11-04 17:17:49 +00003467//VerifyVlanConfigRequest checks on existence of a given uniPort
3468// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003469func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003470 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003471 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003472 for _, uniPort := range dh.uniEntityMap {
3473 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003475 pCurrentUniPort = uniPort
3476 break //found - end search loop
3477 }
3478 }
3479 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003480 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003481 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003482 return
3483 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003485}
3486
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003487//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3488func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003489 //TODO!! verify and start pending flow configuration
3490 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3491 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003492
3493 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003495 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003496 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003497 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003498 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003499 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003500 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3502 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003503 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003504 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003505 } else {
3506 /***** UniVlanConfigFsm continued */
3507 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003508 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3509 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003510 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003511 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3512 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003513 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003514 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003515 } else {
3516 /***** UniVlanConfigFsm continued */
3517 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3519 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003520 }
mpagenkodff5dda2020-08-28 11:52:01 +00003521 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003522 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003523 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3524 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003525 }
3526 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003527 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 +00003528 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3529 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003530 }
3531 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003532 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003534 }
mpagenkof1fc3862021-02-16 10:09:52 +00003535 } else {
3536 dh.lockVlanConfig.RUnlock()
3537 }
mpagenkodff5dda2020-08-28 11:52:01 +00003538}
3539
3540//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3541// 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 +00003542func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003543 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003544 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003545 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003546 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003547 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003548 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003549}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003550
mpagenkof1fc3862021-02-16 10:09:52 +00003551//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003553 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3554 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3555 // obviously then parallel processing on the cancel must be avoided
3556 // deadline context to ensure completion of background routines waited for
3557 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3558 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3559 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3560
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003561 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003562 var wg sync.WaitGroup
3563 wg.Add(1) // for the 1 go routine to finish
3564
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003566 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003568 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003569}
3570
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003571//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003572//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3574 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003576 if dh.IsReconciling() {
3577 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003578 return nil
3579 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003580 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003581
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003582 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003583 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3585 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003586 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003587 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003588
mpagenkof1fc3862021-02-16 10:09:52 +00003589 if aWriteToKvStore {
3590 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3591 }
3592 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003593}
3594
dbainbri4d3a0dc2020-12-02 00:33:42 +00003595func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003596 defer cancel() //ensure termination of context (may be pro forma)
3597 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003598 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003599 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003600}
3601
mpagenkoe4782082021-11-25 12:04:26 +00003602//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3603// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3604func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3605 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3606 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3607 dh.mutexDeviceReason.Lock()
3608 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003609 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003610 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003611 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003612 DeviceId: dh.DeviceID,
3613 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003614 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003615 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003617 return err
3618 }
mpagenkoe4782082021-11-25 12:04:26 +00003619 } else {
3620 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 +00003621 }
mpagenkoe4782082021-11-25 12:04:26 +00003622 dh.deviceReason = deviceReason
3623 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3624 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003625 return nil
3626}
3627
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3629 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003630 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3632 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003633 }
mpagenkof1fc3862021-02-16 10:09:52 +00003634 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003635}
3636
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003637// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003638// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003639func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3640 dh.lockDevice.RLock()
3641 defer dh.lockDevice.RUnlock()
3642 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003643 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003644 }
3645 return 0, errors.New("error-fetching-uni-port")
3646}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003647
3648// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003649func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3650 var errorsList []error
3651 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 -08003652
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003653 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3654 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3655 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3656
3657 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3658 // successfully.
3659 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3660 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3661 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 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 -08003663 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003664 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003666 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003667}
3668
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003669func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3670 var err error
3671 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003672 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003673
3674 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003675 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 errorsList = append(errorsList, err)
3677 }
3678 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003679 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003680
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003681 return errorsList
3682}
3683
3684func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3685 var err error
3686 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003687 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003688 // Check if group metric related config is updated
3689 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3691 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3692 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003693
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 if ok && m.Frequency != v.GroupFreq {
3695 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003696 errorsList = append(errorsList, err)
3697 }
3698 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 if ok && m.Enabled != v.Enabled {
3700 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003701 errorsList = append(errorsList, err)
3702 }
3703 }
3704 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003705 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003706 return errorsList
3707}
3708
3709func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3710 var err error
3711 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003712 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003713 // Check if standalone metric related config is updated
3714 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003715 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3716 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3717 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003718
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719 if ok && m.Frequency != v.SampleFreq {
3720 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003721 errorsList = append(errorsList, err)
3722 }
3723 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003724 if ok && m.Enabled != v.Enabled {
3725 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003726 errorsList = append(errorsList, err)
3727 }
3728 }
3729 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003730 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003731 return errorsList
3732}
3733
3734// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003735func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003736 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003737
3738 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003739 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303740 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003741 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003742 // Initialize the next metric collection time.
3743 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3744 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003745 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003746 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003747 for {
3748 select {
3749 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003750 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003751 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003752 // Stop the L2 PM FSM
3753 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003754 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3755 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3756 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003757 }
3758 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003760 }
3761 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003762 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3763 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003764 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3766 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003767 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003768
Girish Gowdrae09a6202021-01-12 18:10:59 -08003769 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003770 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3771 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3772 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3773 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3774 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003775 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003777 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003778 } else {
3779 if dh.pmConfigs.Grouped { // metrics are managed as a group
3780 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003781 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003782
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003783 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3784 // 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 -08003785 // 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 +00003786 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3787 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003788 }
3789 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003790 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3791 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3792 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3793 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003794 }
3795 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003796 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003797
3798 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003799 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3800 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3801 // 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 -08003802 // 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 +00003803 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3804 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003805 }
3806 }
3807 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3809 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3810 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3811 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003812 }
3813 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003814 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003815 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003816 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003817 } */
3818 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003819 }
3820 }
3821}
kesavandfdf77632021-01-26 23:40:33 -05003822
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003823func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003824
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003825 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3826 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003827}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003828
Himani Chawla43f95ff2021-06-03 00:24:12 +05303829func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3830 if dh.pOnuMetricsMgr == nil {
3831 return &extension.SingleGetValueResponse{
3832 Response: &extension.GetValueResponse{
3833 Status: extension.GetValueResponse_ERROR,
3834 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3835 },
3836 }
3837 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303838 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303839 return resp
3840}
3841
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003842func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3843
3844 var err error
3845 var pDevOmciCC *cmn.OmciCC
3846 if dh.pOnuOmciDevice == nil {
3847 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3848 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3849 } else {
3850 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3851 if pDevOmciCC == nil {
3852 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3853 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3854 }
3855 }
3856 if err != nil {
3857 return &extension.SingleGetValueResponse{
3858 Response: &extension.GetValueResponse{
3859 Status: extension.GetValueResponse_ERROR,
3860 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3861 },
3862 },
3863 err
3864 }
3865 return pDevOmciCC.GetOmciCounters(), nil
3866}
3867
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3869 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003870 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003871 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003872 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003873}
3874
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003875func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003876 var pAdapterFsm *cmn.AdapterFsm
3877 //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 +00003878 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003879 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003880 {
mpagenkofbf577d2021-10-12 11:44:33 +00003881 if dh.pOnuOmciDevice != nil {
3882 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3883 } else {
3884 return true //FSM not active - so there is no activity on omci
3885 }
mpagenkof1fc3862021-02-16 10:09:52 +00003886 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003887 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003888 {
mpagenkofbf577d2021-10-12 11:44:33 +00003889 if dh.pOnuOmciDevice != nil {
3890 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3891 } else {
3892 return true //FSM not active - so there is no activity on omci
3893 }
mpagenkof1fc3862021-02-16 10:09:52 +00003894 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003896 {
mpagenkofbf577d2021-10-12 11:44:33 +00003897 if dh.pLockStateFsm != nil {
3898 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3899 } else {
3900 return true //FSM not active - so there is no activity on omci
3901 }
mpagenkof1fc3862021-02-16 10:09:52 +00003902 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003903 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003904 {
mpagenkofbf577d2021-10-12 11:44:33 +00003905 if dh.pUnlockStateFsm != nil {
3906 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3907 } else {
3908 return true //FSM not active - so there is no activity on omci
3909 }
mpagenkof1fc3862021-02-16 10:09:52 +00003910 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003911 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003912 {
mpagenkofbf577d2021-10-12 11:44:33 +00003913 if dh.pOnuMetricsMgr != nil {
3914 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003915 } else {
3916 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003917 }
3918 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003919 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003920 {
3921 dh.lockUpgradeFsm.RLock()
3922 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003923 if dh.pOnuUpradeFsm != nil {
3924 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3925 } else {
3926 return true //FSM not active - so there is no activity on omci
3927 }
mpagenko80622a52021-02-09 16:53:23 +00003928 }
mpagenkof1fc3862021-02-16 10:09:52 +00003929 default:
3930 {
3931 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003932 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003933 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003934 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003935 }
mpagenkofbf577d2021-10-12 11:44:33 +00003936 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3937 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3938 }
3939 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003940}
3941
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003942func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3943 for _, v := range dh.pOnuTP.PAniConfigFsm {
3944 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003945 return false
3946 }
3947 }
3948 return true
3949}
3950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003951func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003952 dh.lockVlanConfig.RLock()
3953 defer dh.lockVlanConfig.RUnlock()
3954 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003955 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003956 return false
3957 }
3958 }
3959 return true //FSM not active - so there is no activity on omci
3960}
3961
3962func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3963 dh.lockVlanConfig.RLock()
3964 defer dh.lockVlanConfig.RUnlock()
3965 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003966 if v.PAdaptFsm.PFsm != nil {
3967 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003968 return true //there is at least one VLAN FSM with some active configuration
3969 }
3970 }
3971 }
3972 return false //there is no VLAN FSM with some active configuration
3973}
3974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003975func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003976 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3977 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3978 return false
3979 }
3980 }
3981 // a further check is done to identify, if at least some data traffic related configuration exists
3982 // 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])
3983 return dh.checkUserServiceExists(ctx)
3984}
3985
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003986func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003987 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3988 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003989 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003990 // TODO: fatal error reset ONU, delete deviceHandler!
3991 return
3992 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3994 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003995}
3996
3997func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3998 dh.mutexCollectorFlag.Lock()
3999 dh.collectorIsRunning = flagValue
4000 dh.mutexCollectorFlag.Unlock()
4001}
4002
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004003func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00004004 dh.mutexCollectorFlag.RLock()
4005 flagValue := dh.collectorIsRunning
4006 dh.mutexCollectorFlag.RUnlock()
4007 return flagValue
4008}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304009
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304010func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4011 dh.mutextAlarmManagerFlag.Lock()
4012 dh.alarmManagerIsRunning = flagValue
4013 dh.mutextAlarmManagerFlag.Unlock()
4014}
4015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304017 dh.mutextAlarmManagerFlag.RLock()
4018 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004019 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304020 dh.mutextAlarmManagerFlag.RUnlock()
4021 return flagValue
4022}
4023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004025 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304026
4027 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004028 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304029 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304030 if stop := <-dh.stopAlarmManager; stop {
4031 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304032 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05304033 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004034 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4035 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304036 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304037 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004038 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4039 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304040 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304041 }
4042}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004043
Girish Gowdrae95687a2021-09-08 16:30:58 -07004044func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4045 dh.mutexFlowMonitoringRoutineFlag.Lock()
4046 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004047 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004048 dh.isFlowMonitoringRoutineActive[uniID] = flag
4049}
4050
4051func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4052 dh.mutexFlowMonitoringRoutineFlag.RLock()
4053 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4054 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004055 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004056 return dh.isFlowMonitoringRoutineActive[uniID]
4057}
4058
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004059func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
4060 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004061
Maninder7961d722021-06-16 22:10:28 +05304062 connectStatus := voltha.ConnectStatus_UNREACHABLE
4063 operState := voltha.OperStatus_UNKNOWN
4064
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004065 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004066 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004067 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004068 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004069 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004070 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004071 logger.Debugw(ctx, "reconciling finished signal received",
4072 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4073 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4074 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4075 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4076 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4077 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4078 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4079 // However, a later refactoring of the functionality remains unaffected.
4080 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004081 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004082 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304083 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004084 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304085 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004086 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304088 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004089 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4090 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304091 operState = voltha.OperStatus_ACTIVE
4092 } else {
4093 operState = voltha.OperStatus_ACTIVATING
4094 }
4095 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004096 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4097 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4098 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304099 operState = voltha.OperStatus_DISCOVERED
4100 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004101 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004102 logger.Debugw(ctx, "Core DeviceStateUpdate",
4103 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304104 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004105 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004106 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004107 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004108 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004109 ConnStatus: connectStatus,
4110 OperStatus: operState,
4111 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304112 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004113 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304114 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004115 } else {
Maninderb5187552021-03-23 22:23:42 +05304116 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004117 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304118
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004119 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304120 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004121 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004122 } else {
4123 onuDevEntry.MutexPersOnuConfig.RLock()
4124 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4125 connectStatus = voltha.ConnectStatus_REACHABLE
4126 }
4127 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304128 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004129 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004130 }
mpagenko101ac942021-11-16 15:01:29 +00004131 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004132 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004133 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004134 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304135
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004136 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304137 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004138 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004139 } else {
4140 onuDevEntry.MutexPersOnuConfig.RLock()
4141 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4142 connectStatus = voltha.ConnectStatus_REACHABLE
4143 }
4144 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304145 }
4146
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004147 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304148
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004149 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004150 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004151 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004152 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004153 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004154
4155 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4156 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4157 } else {
4158 onuDevEntry.MutexReconciledTpInstances.Lock()
4159 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4160 onuDevEntry.MutexReconciledTpInstances.Unlock()
4161 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004162 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004163 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004164 dh.mutexReconcilingFlag.Lock()
4165 if skipOnuConfig {
4166 dh.reconciling = cSkipOnuConfigReconciling
4167 } else {
4168 dh.reconciling = cOnuConfigReconciling
4169 }
4170 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004171}
4172
mpagenko101ac942021-11-16 15:01:29 +00004173func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004174 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4175 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004176 dh.sendChReconcileFinished(success)
4177 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4178 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4179 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004180 } else {
mpagenko101ac942021-11-16 15:01:29 +00004181 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004182 }
4183}
4184
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004185func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004186 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004187 defer dh.mutexReconcilingFlag.RUnlock()
4188 return dh.reconciling != cNoReconciling
4189}
4190
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004191func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004192 dh.mutexReconcilingFlag.RLock()
4193 defer dh.mutexReconcilingFlag.RUnlock()
4194 return dh.reconciling == cSkipOnuConfigReconciling
4195}
4196
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004197func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4198 dh.mutexReconcilingFirstPassFlag.Lock()
4199 dh.reconcilingFirstPass = value
4200 dh.mutexReconcilingFirstPassFlag.Unlock()
4201}
4202
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004203func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4204 dh.mutexReconcilingReasonUpdate.Lock()
4205 dh.reconcilingReasonUpdate = value
4206 dh.mutexReconcilingReasonUpdate.Unlock()
4207}
4208
4209func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4210 dh.mutexReconcilingReasonUpdate.RLock()
4211 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4212 return dh.reconcilingReasonUpdate
4213}
4214
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004215func (dh *deviceHandler) getDeviceReason() uint8 {
4216 dh.mutexDeviceReason.RLock()
4217 value := dh.deviceReason
4218 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004219 return value
4220}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004221
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004222func (dh *deviceHandler) GetDeviceReasonString() string {
4223 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004224}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004225
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004226func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004227 dh.mutexReadyForOmciConfig.Lock()
4228 dh.readyForOmciConfig = flagValue
4229 dh.mutexReadyForOmciConfig.Unlock()
4230}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004231func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004232 dh.mutexReadyForOmciConfig.RLock()
4233 flagValue := dh.readyForOmciConfig
4234 dh.mutexReadyForOmciConfig.RUnlock()
4235 return flagValue
4236}
Maninder7961d722021-06-16 22:10:28 +05304237
4238func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004239 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304240 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004241 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304242 }
4243
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004244 logger.Debugw(ctx, "Core DeviceStateUpdate",
4245 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004246 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004247 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004248 ConnStatus: connectStatus,
4249 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4250 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304251 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004252 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304253 }
4254}
khenaidoo7d3c5582021-08-11 18:09:44 -04004255
4256/*
4257Helper functions to communicate with Core
4258*/
4259
4260func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4261 cClient, err := dh.coreClient.GetCoreServiceClient()
4262 if err != nil || cClient == nil {
4263 return nil, err
4264 }
4265 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4266 defer cancel()
4267 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4268 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4269}
4270
khenaidoo42dcdfd2021-10-19 17:34:12 -04004271func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004272 cClient, err := dh.coreClient.GetCoreServiceClient()
4273 if err != nil || cClient == nil {
4274 return err
4275 }
4276 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4277 defer cancel()
4278 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004279 logger.Debugw(subCtx, "device-updated-in-core",
4280 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004281 return err
4282}
4283
4284func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4285 cClient, err := dh.coreClient.GetCoreServiceClient()
4286 if err != nil || cClient == nil {
4287 return err
4288 }
4289 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4290 defer cancel()
4291 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004292 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4293 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004294 return err
4295}
4296
4297func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4298 cClient, err := dh.coreClient.GetCoreServiceClient()
4299 if err != nil || cClient == nil {
4300 return err
4301 }
4302 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4303 defer cancel()
4304 _, err = cClient.DeviceUpdate(subCtx, device)
4305 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4306 return err
4307}
4308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004309func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004310 cClient, err := dh.coreClient.GetCoreServiceClient()
4311 if err != nil || cClient == nil {
4312 return err
4313 }
4314 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4315 defer cancel()
4316 _, err = cClient.PortCreated(subCtx, port)
4317 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4318 return err
4319}
4320
khenaidoo42dcdfd2021-10-19 17:34:12 -04004321func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004322 cClient, err := dh.coreClient.GetCoreServiceClient()
4323 if err != nil || cClient == nil {
4324 return err
4325 }
4326 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4327 defer cancel()
4328 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004329 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 -04004330 return err
4331}
4332
khenaidoo42dcdfd2021-10-19 17:34:12 -04004333func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004334 cClient, err := dh.coreClient.GetCoreServiceClient()
4335 if err != nil || cClient == nil {
4336 return err
4337 }
4338 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4339 defer cancel()
4340 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004341 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 -04004342 return err
4343}
4344
4345/*
4346Helper functions to communicate with parent adapter
4347*/
4348
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004349func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4350 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4351
4352 var request = ia.TechProfileInstanceRequestMessage{
4353 DeviceId: dh.DeviceID,
4354 TpInstancePath: aTpPath,
4355 ParentDeviceId: dh.parentID,
4356 ParentPonPort: dh.device.ParentPortNo,
4357 OnuId: dh.device.ProxyAddress.OnuId,
4358 UniId: uint32(aUniID),
4359 }
4360
4361 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004362 if err != nil || pgClient == nil {
4363 return nil, err
4364 }
4365 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4366 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004367 logger.Debugw(subCtx, "get-tech-profile-instance",
4368 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004369 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004370}
4371
Girish Gowdrae95687a2021-09-08 16:30:58 -07004372// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4373// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4374func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4375 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4376 dh.setFlowMonitoringIsRunning(uniID, true)
4377 for {
4378 select {
4379 // block on the channel to receive an incoming flow
4380 // process the flow completely before proceeding to handle the next flow
4381 case flowCb := <-dh.flowCbChan[uniID]:
4382 startTime := time.Now()
4383 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4384 respChan := make(chan error)
4385 if flowCb.addFlow {
4386 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4387 } else {
4388 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4389 }
4390 // Block on response and tunnel it back to the caller
4391 *flowCb.respChan <- <-respChan
4392 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4393 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4394 case <-dh.stopFlowMonitoringRoutine[uniID]:
4395 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4396 dh.setFlowMonitoringIsRunning(uniID, false)
4397 return
4398 }
4399 }
4400}
4401
kesavand011d5162021-11-25 19:21:06 +05304402func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4403 request.ParentDeviceId = dh.GetProxyAddressID()
4404 request.ChildDeviceId = dh.DeviceID
4405 request.ProxyAddress = dh.GetProxyAddress()
4406 request.ConnectStatus = common.ConnectStatus_REACHABLE
4407
4408 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4409 if err != nil || pgClient == nil {
4410 return err
4411 }
4412 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4413 defer cancel()
4414 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4415 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4416 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004417 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4418 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304419 }
4420 return err
4421}
4422
khenaidoo42dcdfd2021-10-19 17:34:12 -04004423func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004424 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4425 if err != nil || pgClient == nil {
4426 return err
4427 }
4428 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4429 defer cancel()
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004430 dh.setOltAvailable(true)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004431 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004432 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4433 if err != nil {
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004434 if status.Code(err) == codes.Unavailable {
4435 dh.setOltAvailable(false)
4436 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004437 logger.Errorw(ctx, "omci-failure",
4438 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004439 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress, "oltAvailable": dh.IsOltAvailable})
khenaidoo7d3c5582021-08-11 18:09:44 -04004440 }
4441 return err
4442}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004443
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004444func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4445 // Check if there are additional TCONT instances necessary/available
4446 pDevEntry.MutexPersOnuConfig.Lock()
4447 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4448 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4449 pDevEntry.MutexPersOnuConfig.Unlock()
4450 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4451 logger.Debugw(ctx, "checking available TCONT instances",
4452 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4453 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4454 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4455 log.Fields{"device-id": dh.device.Id})
4456 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4457 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4458 }
4459 } else {
4460 pDevEntry.MutexPersOnuConfig.Unlock()
4461 }
4462 // Check if there are enough PrioQueue instances available
4463 if dh.pOnuTP != nil {
4464 var numberOfUsPrioQueueDbInsts int
4465
4466 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4467 for _, mgmtEntityID := range queueInstKeys {
4468 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4469 numberOfUsPrioQueueDbInsts++
4470 }
4471 }
4472 // Check if there is an upstream PriorityQueue instance available for each Gem port
4473 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4474 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4475 log.Fields{"device-id": dh.DeviceID,
4476 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4477 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4478 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4479
4480 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4481 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4482 log.Fields{"device-id": dh.device.Id})
4483 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4484 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4485 }
4486 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4487 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4488 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4489 } else {
4490 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4491 log.Fields{"device-id": dh.DeviceID})
4492 }
4493 return nil
4494}
4495
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004496// GetDeviceID - TODO: add comment
4497func (dh *deviceHandler) GetDeviceID() string {
4498 return dh.DeviceID
4499}
4500
4501// GetProxyAddressID - TODO: add comment
4502func (dh *deviceHandler) GetProxyAddressID() string {
4503 return dh.device.ProxyAddress.GetDeviceId()
4504}
4505
4506// GetProxyAddressType - TODO: add comment
4507func (dh *deviceHandler) GetProxyAddressType() string {
4508 return dh.device.ProxyAddress.GetDeviceType()
4509}
4510
4511// GetProxyAddress - TODO: add comment
4512func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4513 return dh.device.ProxyAddress
4514}
4515
4516// GetEventProxy - TODO: add comment
4517func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4518 return dh.EventProxy
4519}
4520
4521// GetOmciTimeout - TODO: add comment
4522func (dh *deviceHandler) GetOmciTimeout() int {
4523 return dh.pOpenOnuAc.omciTimeout
4524}
4525
4526// GetAlarmAuditInterval - TODO: add comment
4527func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4528 return dh.pOpenOnuAc.alarmAuditInterval
4529}
4530
4531// GetDlToOnuTimeout4M - TODO: add comment
4532func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4533 return dh.pOpenOnuAc.dlToOnuTimeout4M
4534}
4535
4536// GetUniEntityMap - TODO: add comment
4537func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4538 return &dh.uniEntityMap
4539}
4540
4541// GetPonPortNumber - TODO: add comment
4542func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4543 return &dh.ponPortNumber
4544}
4545
4546// GetUniVlanConfigFsm - TODO: add comment
4547func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004548 dh.lockVlanConfig.RLock()
4549 value := dh.UniVlanConfigFsmMap[uniID]
4550 dh.lockVlanConfig.RUnlock()
4551 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004552}
4553
4554// GetOnuAlarmManager - TODO: add comment
4555func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4556 return dh.pAlarmMgr
4557}
4558
4559// GetOnuMetricsManager - TODO: add comment
4560func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4561 return dh.pOnuMetricsMgr
4562}
4563
4564// GetOnuTP - TODO: add comment
4565func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4566 return dh.pOnuTP
4567}
4568
4569// GetBackendPathPrefix - TODO: add comment
4570func (dh *deviceHandler) GetBackendPathPrefix() string {
4571 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4572}
4573
4574// GetOnuIndication - TODO: add comment
4575func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4576 return dh.pOnuIndication
4577}
4578
4579// RLockMutexDeletionInProgressFlag - TODO: add comment
4580func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4581 dh.mutexDeletionInProgressFlag.RLock()
4582}
4583
4584// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4585func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4586 dh.mutexDeletionInProgressFlag.RUnlock()
4587}
4588
4589// GetDeletionInProgress - TODO: add comment
4590func (dh *deviceHandler) GetDeletionInProgress() bool {
4591 return dh.deletionInProgress
4592}
4593
4594// GetPmConfigs - TODO: add comment
4595func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4596 return dh.pmConfigs
4597}
4598
4599// GetDeviceType - TODO: add comment
4600func (dh *deviceHandler) GetDeviceType() string {
4601 return dh.DeviceType
4602}
4603
4604// GetLogicalDeviceID - TODO: add comment
4605func (dh *deviceHandler) GetLogicalDeviceID() string {
4606 return dh.logicalDeviceID
4607}
4608
4609// GetDevice - TODO: add comment
4610func (dh *deviceHandler) GetDevice() *voltha.Device {
4611 return dh.device
4612}
4613
Holger Hildebrandt2b107642022-12-09 07:56:23 +00004614func (dh *deviceHandler) setOltAvailable(value bool) {
4615 dh.mutexOltAvailable.Lock()
4616 dh.oltAvailable = value
4617 dh.mutexOltAvailable.Unlock()
4618}
4619
4620// IsOltAvailable - TODO: add comment
4621func (dh *deviceHandler) IsOltAvailable() bool {
4622 dh.mutexOltAvailable.RLock()
4623 defer dh.mutexOltAvailable.RUnlock()
4624 return dh.oltAvailable
4625}
4626
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004627// GetMetricsEnabled - TODO: add comment
4628func (dh *deviceHandler) GetMetricsEnabled() bool {
4629 return dh.pOpenOnuAc.MetricsEnabled
4630}
4631
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004632// GetExtendedOmciSupportEnabled - TODO: add comment
4633func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4634 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4635}
4636
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004637// InitPmConfigs - TODO: add comment
4638func (dh *deviceHandler) InitPmConfigs() {
4639 dh.pmConfigs = &voltha.PmConfigs{}
4640}
4641
4642// GetUniPortMask - TODO: add comment
4643func (dh *deviceHandler) GetUniPortMask() int {
4644 return dh.pOpenOnuAc.config.UniPortMask
4645}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004646
4647func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4648 tpPathFound := false
4649 for _, tpPath := range aTpPathMap {
4650 if tpPath != "" {
4651 tpPathFound = true
4652 }
4653 }
4654 return tpPathFound
4655}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004656
4657// PrepareForGarbageCollection - remove references to prepare for garbage collection
4658func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4659 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4660
4661 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4662 // first let the objects rest for some time to give all asynchronously started
4663 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004664 time.Sleep(2 * time.Second)
4665
4666 if dh.pOnuOmciDevice != nil {
4667 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4668 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4669 // reset handling (even in future coding), request monitoring is canceled here one last time to
4670 // be sure that all corresponding go routines are terminated
4671 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4672 }
4673 }
4674 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004675
4676 if dh.pOnuTP != nil {
4677 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4678 }
4679 if dh.pOnuMetricsMgr != nil {
4680 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
Girish Gowdraabcceb12022-04-13 23:35:22 -07004681 select {
4682 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4683 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4684 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4685 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
4686 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004687 }
4688 if dh.pAlarmMgr != nil {
4689 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4690 }
4691 if dh.pSelfTestHdlr != nil {
4692 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4693 }
4694 if dh.pLockStateFsm != nil {
4695 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4696 }
4697 if dh.pUnlockStateFsm != nil {
4698 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4699 }
4700 if dh.pOnuUpradeFsm != nil {
4701 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4702 }
4703 if dh.pOnuOmciDevice != nil {
4704 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4705 }
4706 for k, v := range dh.UniVlanConfigFsmMap {
4707 v.PrepareForGarbageCollection(ctx, aDeviceID)
4708 delete(dh.UniVlanConfigFsmMap, k)
4709 }
4710 dh.pOnuOmciDevice = nil
4711 dh.pOnuTP = nil
4712 dh.pOnuMetricsMgr = nil
4713 dh.pAlarmMgr = nil
4714 dh.pSelfTestHdlr = nil
4715 dh.pLockStateFsm = nil
4716 dh.pUnlockStateFsm = nil
4717 dh.pOnuUpradeFsm = nil
4718}