blob: 744834a4d6ab99f543fa4de4dc301896fe74605f [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
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 Hildebrandt0f9b88d2020-04-20 13:33:25 +000058)
59
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060const (
mpagenko101ac942021-11-16 15:01:29 +000061 //constants for reconcile flow check channel
62 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
63 cWaitReconcileFlowAbortOnError = 0xFFFE
64 cWaitReconcileFlowNoActivity = 0xFFFF
65)
66
67const (
68 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000069 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000071
mpagenko1cc3cb42020-07-27 15:24:38 +000072const (
mpagenko44bd8362021-11-15 11:40:05 +000073 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
74 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
75 // as long as such is not available by the libraries - use this workaround
76 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
77)
78
79const (
mpagenko1cc3cb42020-07-27 15:24:38 +000080 // events of Device FSM
81 devEvDeviceInit = "devEvDeviceInit"
82 devEvGrpcConnected = "devEvGrpcConnected"
83 devEvGrpcDisconnected = "devEvGrpcDisconnected"
84 devEvDeviceUpInd = "devEvDeviceUpInd"
85 devEvDeviceDownInd = "devEvDeviceDownInd"
86)
87const (
88 // states of Device FSM
89 devStNull = "devStNull"
90 devStDown = "devStDown"
91 devStInit = "devStInit"
92 devStConnected = "devStConnected"
93 devStUp = "devStUp"
94)
95
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
97const (
Himani Chawla4d908332020-08-31 12:30:20 +053098 pon = voltha.EventSubCategory_PON
99 //olt = voltha.EventSubCategory_OLT
100 //ont = voltha.EventSubCategory_ONT
101 //onu = voltha.EventSubCategory_ONU
102 //nni = voltha.EventSubCategory_NNI
103 //service = voltha.EventCategory_SERVICE
104 //security = voltha.EventCategory_SECURITY
105 equipment = voltha.EventCategory_EQUIPMENT
106 //processing = voltha.EventCategory_PROCESSING
107 //environment = voltha.EventCategory_ENVIRONMENT
108 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000109)
110
111const (
112 cEventObjectType = "ONU"
113)
114const (
115 cOnuActivatedEvent = "ONU_ACTIVATED"
116)
117
mpagenkof1fc3862021-02-16 10:09:52 +0000118type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000120 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
124 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
125 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
126 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
128 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
129 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
130 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
131 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000132}
133
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000134const (
135 cNoReconciling = iota
136 cOnuConfigReconciling
137 cSkipOnuConfigReconciling
138)
139
Girish Gowdrae95687a2021-09-08 16:30:58 -0700140// FlowCb is the flow control block containing flow add/delete information along with a response channel
141type FlowCb struct {
142 ctx context.Context // Flow handler context
143 addFlow bool // if true flow to be added, else removed
144 flowItem *of.OfpFlowStats
145 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400146 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147 respChan *chan error // channel to report the Flow handling error
148}
149
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150//deviceHandler will interact with the ONU ? device.
151type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 DeviceType string
154 adminState string
155 device *voltha.Device
156 logicalDeviceID string
157 ProxyAddressID string
158 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530159 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000160 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161
khenaidoo7d3c5582021-08-11 18:09:44 -0400162 coreClient *vgrpc.Client
163 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000164
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800165 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400166 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800167
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000168 pOpenOnuAc *OpenONUAC
169 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530170 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000171 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000172 pOnuOmciDevice *mib.OnuDeviceEntry
173 pOnuTP *avcfg.OnuUniTechProf
174 pOnuMetricsMgr *pmmgr.OnuMetricsManager
175 pAlarmMgr *almgr.OnuAlarmManager
176 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000177 exitChannel chan int
178 lockDevice sync.RWMutex
179 pOnuIndication *oop.OnuIndication
180 deviceReason uint8
181 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000182 pLockStateFsm *uniprt.LockStateFsm
183 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 //flowMgr *OpenOltFlowMgr
186 //eventMgr *OpenOltEventMgr
187 //resourceMgr *rsrcMgr.OpenOltResourceMgr
188
189 //discOnus sync.Map
190 //onus sync.Map
191 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000192 collectorIsRunning bool
193 mutexCollectorFlag sync.RWMutex
194 stopCollector chan bool
195 alarmManagerIsRunning bool
196 mutextAlarmManagerFlag sync.RWMutex
197 stopAlarmManager chan bool
198 stopHeartbeatCheck chan bool
199 uniEntityMap cmn.OnuUniPortMap
200 mutexKvStoreContext sync.Mutex
201 lockVlanConfig sync.RWMutex
202 lockVlanAdd sync.RWMutex
203 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
204 lockUpgradeFsm sync.RWMutex
205 pOnuUpradeFsm *swupg.OnuUpgradeFsm
206 upgradeCanceled bool
207 reconciling uint8
208 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000209 reconcilingFirstPass bool
210 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000211 reconcilingReasonUpdate bool
212 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000213 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
214 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
215 reconcileExpiryComplete time.Duration
216 reconcileExpiryVlanConfig time.Duration
217 mutexReadyForOmciConfig sync.RWMutex
218 readyForOmciConfig bool
219 deletionInProgress bool
220 mutexDeletionInProgressFlag sync.RWMutex
221 pLastUpgradeImageState *voltha.ImageState
222 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700223
224 flowCbChan []chan FlowCb
225 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300226 mutexForDisableDeviceRequested sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700227 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
228 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300229 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400233func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530234 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400235 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400237 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000239 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.DeviceType = cloned.Type
241 dh.adminState = "up"
242 dh.device = cloned
243 dh.pOpenOnuAc = adapter
244 dh.exitChannel = make(chan int, 1)
245 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000246 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000247 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530249 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530250 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 dh.stopHeartbeatCheck = make(chan bool, 2)
252 //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 +0000253 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000255 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000256 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000257 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300258 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000260 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000261 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000262 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300263 dh.disableDeviceRequested = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000264 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000265 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
266 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
267 if rECSeconds < 2 {
268 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
269 rECSeconds = 2
270 }
271 rEVCSeconds := rECSeconds / 2
272 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000273 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000274 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000275 dh.pLastUpgradeImageState = &voltha.ImageState{
276 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
277 Reason: voltha.ImageState_UNKNOWN_ERROR,
278 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
279 }
280 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800282 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
283 dh.pmConfigs = cloned.PmConfigs
284 } /* else {
285 // will be populated when onu_metrics_mananger is initialized.
286 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800287
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 // Device related state machine
289 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000290 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000292 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
293 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
294 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
295 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
296 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 },
298 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
300 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
301 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
302 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
303 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
304 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
305 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
306 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 },
308 )
mpagenkoaf801632020-07-03 10:00:42 +0000309
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 return &dh
311}
312
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313// start save the device to the data model
314func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000317 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318}
319
Himani Chawla4d908332020-08-31 12:30:20 +0530320/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323 logger.Debug("stopping-device-handler")
324 dh.exitChannel <- 1
325}
Himani Chawla4d908332020-08-31 12:30:20 +0530326*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327
328// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530329// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330
Girish Gowdrae0140f02021-02-02 16:55:09 -0800331//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530332func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400333 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000336 if dh.pDeviceStateFsm.Is(devStNull) {
337 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000338 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 +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())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800341 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
342 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800343 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400344 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800346 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800347 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000348 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000350 }
351
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000352}
353
khenaidoo42dcdfd2021-10-19 17:34:12 -0400354func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000355 /* 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 +0530356 //assuming omci message content is hex coded!
357 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000360 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000363 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000365 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000366 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
367 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
370 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530371}
372
khenaidoo42dcdfd2021-10-19 17:34:12 -0400373func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000377 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
379 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 if dh.pOnuTP == nil {
382 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 log.Fields{"device-id": dh.DeviceID})
385 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 if !dh.IsReadyForOmciConfig() {
388 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
389 "device-state": dh.GetDeviceReasonString()})
390 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000392 //previous state test here was just this one, now extended for more states to reject the SetRequest:
393 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
394 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
398 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 dh.pOnuTP.LockTpProcMutex()
400 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
mpagenko44bd8362021-11-15 11:40:05 +0000402 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 }
406 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000409 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
410 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800411 return err
412 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000413 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
414 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000416 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530417
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400419 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000420 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
421 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +0000422
423 err = dh.CheckAvailableOnuCapabilities(ctx, pDevEntry, *tpInst.TpInstance)
424 if err != nil {
425 logger.Errorw(ctx, "error-checking-available-onu-capabilities-stopping-device",
426 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
427 // stopping all further processing
428 _ = dh.UpdateInterface(ctx)
429 return err
430 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700431 // if there has been some change for some uni TechProfilePath
432 //in order to allow concurrent calls to other dh instances we do not wait for execution here
433 //but doing so we can not indicate problems to the caller (who does what with that then?)
434 //by now we just assume straightforward successful execution
435 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
436 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530437
Girish Gowdra50e56422021-06-01 16:46:04 -0700438 // deadline context to ensure completion of background routines waited for
439 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
440 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
441 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000443 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700444
445 var wg sync.WaitGroup
446 wg.Add(1) // for the 1 go routine to finish
447 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700449 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000450 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
451 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 -0700452 return tpErr
453 }
454 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
455 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700457 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000458 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700459 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
461 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 -0700462 return kvErr
463 }
464 return nil
465 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000466 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700467 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700468 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530469 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000471 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
472 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 return nil
474}
475
khenaidoo42dcdfd2021-10-19 17:34:12 -0400476func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000477 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530478
479 if dh.pOnuTP == nil {
480 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000482 log.Fields{"device-id": dh.DeviceID})
483 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530484 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 dh.pOnuTP.LockTpProcMutex()
487 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530488
mpagenko0f543222021-11-03 16:24:14 +0000489 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
490 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
491 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000492 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000494 }
495 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800497 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000498 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
499 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800500 return err
501 }
mpagenko0f543222021-11-03 16:24:14 +0000502 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
503 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000504 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000505
Mahir Gunyel9545be22021-07-04 15:53:16 -0700506 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000508
Himani Chawla26e555c2020-08-31 12:30:20 +0530509}
510
khenaidoo42dcdfd2021-10-19 17:34:12 -0400511func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000512 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 +0000513
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000514 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000515 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000516 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
517 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000518 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 if dh.pOnuTP == nil {
520 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000522 log.Fields{"device-id": dh.DeviceID})
523 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530524 }
525
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000527 dh.pOnuTP.LockTpProcMutex()
528 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000529
mpagenko0f543222021-11-03 16:24:14 +0000530 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
531 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
532 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000535 }
536 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700537 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000538 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800539 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000540 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
541 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800542 return err
543 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000544 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530545
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000546 var wg sync.WaitGroup
547 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
548 dctx, cancel := context.WithDeadline(context.Background(), deadline)
549 wg.Add(1)
550 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
551 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
552 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
553 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
554 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
555 return err
556 }
557
Mahir Gunyel9545be22021-07-04 15:53:16 -0700558 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000562
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
565 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700566 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
568 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530569 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700570 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572 resourceName = "Gem"
573 } else {
574 resourceName = "Tcont"
575 }
576
577 // deadline context to ensure completion of background routines waited for
578 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
579 dctx, cancel := context.WithDeadline(context.Background(), deadline)
580
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700582
583 var wg sync.WaitGroup
584 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700586 resource, entryID, &wg)
587 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
589 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700590 return err
591 }
592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
594 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
595 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
596 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700597 var wg2 sync.WaitGroup
598 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
599 wg2.Add(1)
600 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000601 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 +0000602 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700603 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000604 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
605 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700606 return err
607 }
608 }
609 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700611 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530612 return nil
613}
614
mpagenkodff5dda2020-08-28 11:52:01 +0000615//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400617 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400618 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
620 var errorsList []error
621 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000622 //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 +0000623 if apOfFlowChanges.ToRemove != nil {
624 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000625 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000627 "device-id": dh.DeviceID})
628 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700629 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000630 continue
631 }
632 flowInPort := flow.GetInPort(flowItem)
633 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
635 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700636 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000637 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000639 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000640 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000643 continue
644 } else {
645 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000647 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
648 loUniPort = uniPort
649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000650 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000651 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000652 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000653 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700654 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000655 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000656 }
657 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
660 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700661
662 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
663 // Step1 : Fill flowControlBlock
664 // Step2 : Push the flowControlBlock to ONU channel
665 // Step3 : Wait on response channel for response
666 // Step4 : Return error value
667 startTime := time.Now()
668 respChan := make(chan error)
669 flowCb := FlowCb{
670 ctx: ctx,
671 addFlow: false,
672 flowItem: flowItem,
673 flowMetaData: nil,
674 uniPort: loUniPort,
675 respChan: &respChan,
676 }
677 dh.flowCbChan[loUniPort.UniID] <- flowCb
678 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
679 // Wait on the channel for flow handlers return value
680 retError = <-respChan
681 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
682 if retError != nil {
683 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
684 log.Fields{"device-id": dh.DeviceID, "error": retError})
685 errorsList = append(errorsList, retError)
686 continue
687 }
688 } else {
689 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
690 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000691 }
692 }
693 }
694 }
mpagenko01e726e2020-10-23 09:45:29 +0000695 if apOfFlowChanges.ToAdd != nil {
696 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
697 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000699 "device-id": dh.DeviceID})
700 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700701 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000702 continue
703 }
704 flowInPort := flow.GetInPort(flowItem)
705 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000706 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
707 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700708 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000709 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000711 } else if flowInPort == dh.ponPortNumber {
712 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000715 continue
716 } else {
717 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000718 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000719 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
720 loUniPort = uniPort
721 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000722 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000723 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000724 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700726 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000727 continue
mpagenko01e726e2020-10-23 09:45:29 +0000728 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000729 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
730 // if not, we just throw some error here to have an indication about that, if we really need to support that
731 // then we would need to create some means to activate the internal stored flows
732 // after the device gets active automatically (and still with its dependency to the TechProfile)
733 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
734 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000735 if !dh.IsReadyForOmciConfig() {
736 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
737 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700738 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
739 errorsList = append(errorsList, retError)
740 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000741 }
742
mpagenko01e726e2020-10-23 09:45:29 +0000743 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000745 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
746 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700747 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
748 // Step1 : Fill flowControlBlock
749 // Step2 : Push the flowControlBlock to ONU channel
750 // Step3 : Wait on response channel for response
751 // Step4 : Return error value
752 startTime := time.Now()
753 respChan := make(chan error)
754 flowCb := FlowCb{
755 ctx: ctx,
756 addFlow: true,
757 flowItem: flowItem,
758 flowMetaData: apFlowMetaData,
759 uniPort: loUniPort,
760 respChan: &respChan,
761 }
762 dh.flowCbChan[loUniPort.UniID] <- flowCb
763 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
764 // Wait on the channel for flow handlers return value
765 retError = <-respChan
766 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
767 if retError != nil {
768 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
769 log.Fields{"device-id": dh.DeviceID, "error": retError})
770 errorsList = append(errorsList, retError)
771 continue
772 }
773 } else {
774 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
775 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000776 }
777 }
778 }
779 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700780 if len(errorsList) > 0 {
781 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
782 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
783 }
784 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000785}
786
Himani Chawla6d2ae152020-09-02 13:11:20 +0530787//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000788//following are the expected device states after this activity:
789//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
790// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
792 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300793 dh.mutexForDisableDeviceRequested.Lock()
794 dh.disableDeviceRequested = true
795 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000796 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000797 //note that disableDevice sequences in some 'ONU active' state may yield also
798 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000799 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000801 //disable-device shall be just a UNi/ONU-G related admin state setting
802 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000803
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000804 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000805 // disable UNI ports/ONU
806 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
807 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000809 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000811 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000812 }
813 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000814 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000815 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000816 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400817 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000818 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000819 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400820 OperStatus: voltha.OperStatus_UNKNOWN,
821 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000822 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000824 }
mpagenko01e726e2020-10-23 09:45:29 +0000825 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000826
827 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000828 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000829 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300830 }
831}
832
Himani Chawla6d2ae152020-09-02 13:11:20 +0530833//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
835 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000836
mpagenkoaa3afe92021-05-21 16:20:58 +0000837 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000838 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
839 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
840 // for real ONU's that should have nearly no influence
841 // Note that for real ONU's there is anyway a problematic situation with following sequence:
842 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
843 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
844 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000845 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000846
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000847 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000848 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300849 dh.mutexForDisableDeviceRequested.Lock()
850 dh.disableDeviceRequested = false
851 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000852 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000854 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000857 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300858}
859
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000862
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000864 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000865 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 return
867 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000869 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000870 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000871 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000872 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000873 }
mpagenko101ac942021-11-16 15:01:29 +0000874 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000875 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000876 }
Himani Chawla4d908332020-08-31 12:30:20 +0530877 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 pDevEntry.MutexPersOnuConfig.RLock()
879 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
880 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
881 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
882 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
883 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000884 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000885}
886
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000887func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000889
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000890 continueWithFlowConfig := false
891
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000893 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000894 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000895 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
896 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000897 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000898 dh.pOnuTP.LockTpProcMutex()
899 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000900
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000901 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000902 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000903 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
904 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000905 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000907 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
908 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000909 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000910 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700911 techProfsFound := false
912 techProfInstLoadFailed := false
913outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000915 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000916 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000917 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000918 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000919 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000920 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000922 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
923 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000924 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000926 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000928 var iaTechTpInst ia.TechProfileDownloadMessage
929 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800930 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000931 pDevEntry.MutexReconciledTpInstances.RLock()
932 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
933 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000934 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000935 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700938 break outerLoop
939 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000940 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000941 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 var tpInst tech_profile.TechProfileInstance
943 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400944 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700945 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000946 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000947 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700948 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000949 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700951 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
952 break outerLoop
953 }
954
Girish Gowdra041dcb32020-11-16 16:54:30 -0800955 // deadline context to ensure completion of background routines waited for
956 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
957 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000958 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000959
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800961 var wg sync.WaitGroup
962 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000963 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000964 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
966 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700967 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
968 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800969 }
mpagenko2dc896e2021-08-02 12:03:59 +0000970 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 if len(uniData.PersFlowParams) != 0 {
972 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000973 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000974 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000975 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 } // for all UNI entries from SOnuPersistentData
977 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
978 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000979 }
mpagenko2dc896e2021-08-02 12:03:59 +0000980
981 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
982 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000983
984 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000985}
986
987func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
988 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
989 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000990 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000991 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000992 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000993 return
994 }
mpagenko2dc896e2021-08-02 12:03:59 +0000995 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000996 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000997 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700998 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001000 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 }
mpagenko2dc896e2021-08-02 12:03:59 +00001002 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001003 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001004 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001005 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001007}
1008
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001009func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1010 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001011
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001012 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001013 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001014 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001015 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001016 return
1017 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 pDevEntry.MutexPersOnuConfig.RLock()
1020 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1021 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001022 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001023 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001024 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001025 return
1026 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001028 var uniVlanConfigEntries []uint8
1029 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1030
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001032 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1033 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001034 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001036 continue
1037 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001038 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001039 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001041 // It doesn't make sense to configure any flows if no TPs are available
1042 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001043 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1045 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001046 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001048
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001051 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001052 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1054 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001055 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001056 return
1057 }
mpagenko101ac942021-11-16 15:01:29 +00001058 //needed to split up function due to sca complexity
1059 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1060
mpagenko2dc896e2021-08-02 12:03:59 +00001061 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001062 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001063 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1064 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001065 // this can't be used as global finished reconciling flag because
1066 // assumes is getting called before the state machines for the last flow is completed,
1067 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1069 } // for all UNI entries from SOnuPersistentData
1070 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001071
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001072 if !flowsFound {
1073 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001074 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001075 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001076 return
1077 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001078 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1079 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1080 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1081 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1082 log.Fields{"device-id": dh.DeviceID})
1083 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1084 if pDevEntry != nil {
1085 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001086 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001087 } else {
1088 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1089 log.Fields{"device-id": dh.DeviceID})
1090 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1091 if pDevEntry != nil {
1092 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1093 }
1094 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001095 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001096 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001097}
1098
mpagenko101ac942021-11-16 15:01:29 +00001099func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1100 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1101 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1102 flowsProcessed := 0
1103 lastFlowToReconcile := false
1104 loUniID := apUniPort.UniID
1105 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001106 if !(*apFlowsFound) {
1107 *apFlowsFound = true
1108 syncChannel := make(chan struct{})
1109 // start go routine with select() on reconciling vlan config channel before
1110 // starting vlan config reconciling process to prevent loss of any signal
1111 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1112 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1113 //block until the wait routine is really blocked on channel input
1114 // in order to prevent to early ready signal from VlanConfig processing
1115 <-syncChannel
1116 }
1117 if flowsProcessed == len(aPersFlowParam)-1 {
1118 var uniAdded bool
1119 lastFlowToReconcile = true
1120 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1121 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001122 }
1123 }
mpagenko101ac942021-11-16 15:01:29 +00001124 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1125 "device-id": dh.DeviceID, "uni-id": loUniID,
1126 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1127 dh.lockVlanConfig.Lock()
1128 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1129 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1130 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301131 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 +00001132 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1133 }
1134 } else {
1135 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301136 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05301137 uint8(flowData.VlanRuleParams.SetPcp), flowData.VlanRuleParams.InnerCvlan, cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
mpagenko101ac942021-11-16 15:01:29 +00001138 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1139 }
1140 }
1141 dh.lockVlanConfig.Unlock()
1142 flowsProcessed++
1143 } //for all flows of this UNI
1144}
1145
1146//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1147// and decrements the according handler wait group waiting for these indications
1148func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1149 waitGroup *cmn.WaitGroupWithTimeOut) {
1150 var reconciledUniVlanConfigEntries []uint8
1151 var appended bool
1152 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1153 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1154 "device-id": dh.DeviceID, "expiry": expiry})
1155 // indicate blocking on channel now to the caller
1156 aSyncChannel <- struct{}{}
1157 for {
1158 select {
1159 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1160 switch uniIndication {
1161 // no activity requested (should normally not be received) - just continue waiting
1162 case cWaitReconcileFlowNoActivity:
1163 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1164 case cWaitReconcileFlowAbortOnError:
1165 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1166 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1167 return
1168 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1169 case cWaitReconcileFlowAbortOnSuccess:
1170 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1171 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1172 return
1173 // this should be a valid UNI vlan config done indication
1174 default:
1175 if uniIndication < platform.MaxUnisPerOnu {
1176 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1177 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1178 if reconciledUniVlanConfigEntries, appended =
1179 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1180 waitGroup.Done()
1181 }
1182 } else {
1183 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1184 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1185 }
1186 } //switch uniIndication
1187
1188 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1189 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1190 log.Fields{"device-id": dh.DeviceID})
1191 return
1192 }
1193 }
1194}
1195
1196func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1197 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1198}
1199
1200func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1201 for _, ele := range slice {
1202 if ele == val {
1203 return slice, false
1204 }
1205 }
1206 return append(slice, val), true
1207}
1208
1209// sendChReconcileFinished - sends true or false on reconcileFinish channel
1210func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1211 if dh != nil { //if the object still exists (might have been already deleted in background)
1212 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1213 select {
1214 case dh.chReconcilingFinished <- success:
1215 default:
1216 }
1217 }
1218}
1219
1220// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1221func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1222 if dh != nil { //if the object still exists (might have been already deleted in background)
1223 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1224 select {
1225 case dh.chUniVlanConfigReconcilingDone <- value:
1226 default:
1227 }
1228 }
1229}
1230
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001233
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001235 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001236 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001238 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001239 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001240
1241 // deadline context to ensure completion of background routines waited for
1242 //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 +05301243 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001245
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001247
1248 var wg sync.WaitGroup
1249 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001252
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001253 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001254 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001255}
1256
mpagenko15ff4a52021-03-02 10:09:20 +00001257//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1258// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001260//was and is called in background - error return does not make sense
1261func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001263 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001265 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001266 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301268 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001270 return
Himani Chawla4d908332020-08-31 12:30:20 +05301271 }
mpagenko01e726e2020-10-23 09:45:29 +00001272
1273 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001275
mpagenko44bd8362021-11-15 11:40:05 +00001276 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001278 // 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 -04001279 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001281 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001282 OperStatus: voltha.OperStatus_DISCOVERED,
1283 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001284 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001286 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001287 }
mpagenkoe4782082021-11-25 12:04:26 +00001288 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001289 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001290 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001291 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001292 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1293 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1294 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1295 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001296}
1297
mpagenkoc8bba412021-01-15 15:38:44 +00001298//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001299// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001300func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001301 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001302 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001304
1305 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001307 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1309 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001310 }
1311
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001312 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001313 var inactiveImageID uint16
1314 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1315 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001316 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1317 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001318 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001320 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001321 if err == nil {
1322 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1323 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001325 }
1326 } else {
1327 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001328 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001329 }
mpagenko15ff4a52021-03-02 10:09:20 +00001330 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001331 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001332 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001333 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1334 dh.upgradeCanceled = true
1335 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1336 }
mpagenko38662d02021-08-11 09:45:19 +00001337 //no effort spent anymore for the old API to automatically cancel and restart the download
1338 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001339 }
mpagenko15ff4a52021-03-02 10:09:20 +00001340 } else {
1341 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001343 }
1344 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001345 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1346 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001347 }
1348 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001349}
1350
mpagenkoc26d4c02021-05-06 14:27:57 +00001351//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1352// after the OnuImage has been downloaded to the adapter, called in background
1353func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001355
1356 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001358 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001360 return
1361 }
1362
1363 var inactiveImageID uint16
1364 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1365 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001367
mpagenko59862f02021-10-11 08:53:18 +00001368 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001369 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001370 // but must be still locked at calling createOnuUpgradeFsm
1371 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1372 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1373 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001374 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1375 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001376 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001377 //flush the remove upgradeFsmChan channel
1378 select {
1379 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001380 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001381 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001382 }
mpagenko59862f02021-10-11 08:53:18 +00001383 dh.lockUpgradeFsm.Unlock()
1384 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1385 dh.upgradeCanceled = true
1386 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1387 }
mpagenko38662d02021-08-11 09:45:19 +00001388 select {
1389 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001391 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1392 return
1393 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001394 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001395 }
mpagenko59862f02021-10-11 08:53:18 +00001396 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001397 }
mpagenko38662d02021-08-11 09:45:19 +00001398
1399 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001400 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001401 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001403 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001404 if err == nil {
1405 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1406 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1407 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001409 return
1410 }
mpagenko38662d02021-08-11 09:45:19 +00001411 } else {
1412 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001414 }
1415 return
1416 }
1417 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001419}
1420
1421//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001422func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1423 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 var err error
1425 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1426 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1427 // 2.) activation of the inactive image
1428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001429 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001430 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1432 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001433 }
1434 dh.lockUpgradeFsm.RLock()
1435 if dh.pOnuUpradeFsm != nil {
1436 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001437 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001438 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001439 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1440 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001441 }
mpagenko59862f02021-10-11 08:53:18 +00001442 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1443 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1444 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1445 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001446 // use the OnuVendor identification from this device for the internal unique name
1447 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001448 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001449 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001450 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001452 "device-id": dh.DeviceID, "error": err})
1453 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001454 }
mpagenko183647c2021-06-08 15:25:04 +00001455 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001456 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001457 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001458 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001459 } //else
1460 dh.lockUpgradeFsm.RUnlock()
1461
1462 // 2.) check if requested image-version equals the inactive one and start its activation
1463 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1464 var inactiveImageID uint16
1465 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1466 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1468 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001469 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001470 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001472 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001473 if err == nil {
1474 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1475 inactiveImageID, aCommitRequest); err != nil {
1476 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 "device-id": dh.DeviceID, "error": err})
1478 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001479 }
1480 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001481 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001482 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001483 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 } //else
1485 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 "device-id": dh.DeviceID, "error": err})
1487 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001488}
1489
1490//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001491func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1492 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 var err error
1494 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1495 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1496 // 2.) commitment of the active image
1497
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001499 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1501 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001502 }
1503 dh.lockUpgradeFsm.RLock()
1504 if dh.pOnuUpradeFsm != nil {
1505 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001506 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001507 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1509 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001510 }
mpagenko59862f02021-10-11 08:53:18 +00001511 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1512 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1513 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1514 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001515 // use the OnuVendor identification from this device for the internal unique name
1516 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001517 // 1.) check a started upgrade process and relay the commitment request to it
1518 // the running upgrade may be based either on the imageIdentifier (started from download)
1519 // or on the imageVersion (started from pure activation)
1520 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1521 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001522 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001523 "device-id": dh.DeviceID, "error": err})
1524 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 }
mpagenko183647c2021-06-08 15:25:04 +00001526 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001527 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001528 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001529 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 } //else
1531 dh.lockUpgradeFsm.RUnlock()
1532
mpagenko183647c2021-06-08 15:25:04 +00001533 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 var activeImageID uint16
1535 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1536 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1538 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001540 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001541 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001542 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001543 if err == nil {
1544 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1545 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 "device-id": dh.DeviceID, "error": err})
1547 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001548 }
1549 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001550 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001551 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001552 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001553 } //else
1554 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 "device-id": dh.DeviceID, "error": err})
1556 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001557}
1558
mpagenkoaa3afe92021-05-21 16:20:58 +00001559func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001560 aVersion string) *voltha.ImageState {
1561 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001562 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001563 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001564 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001565 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1566 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1567 if aVersion == dh.pLastUpgradeImageState.Version {
1568 pImageState = dh.pLastUpgradeImageState
1569 } else { //state request for an image version different from last processed image version
1570 pImageState = &voltha.ImageState{
1571 Version: aVersion,
1572 //we cannot state something concerning this version
1573 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1574 Reason: voltha.ImageState_NO_ERROR,
1575 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1576 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001577 }
1578 }
mpagenko38662d02021-08-11 09:45:19 +00001579 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001580}
1581
1582func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1583 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001584 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001585 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001586 dh.lockUpgradeFsm.RLock()
1587 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001588 dh.lockUpgradeFsm.RUnlock()
1589 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001590 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001591 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1592 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1593 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1594 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1595 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1596 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001597 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1598 dh.upgradeCanceled = true
1599 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1600 }
mpagenko45586762021-10-01 08:30:22 +00001601 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001602 } else {
mpagenko45586762021-10-01 08:30:22 +00001603 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001604 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1605 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1606 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1607 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1608 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1609 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001610 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1611 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001612 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1613 //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 +00001614 }
1615}
1616
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001617func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1618
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001620
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1624 pDevEntry.MutexOnuImageStatus.Lock()
1625 pDevEntry.POnuImageStatus = onuImageStatus
1626 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627
1628 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001630 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1631 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1633 pDevEntry.MutexOnuImageStatus.Lock()
1634 pDevEntry.POnuImageStatus = nil
1635 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001636 return images, err
1637}
1638
Himani Chawla6d2ae152020-09-02 13:11:20 +05301639// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001640// #####################################################################################
1641
1642// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301643// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001646 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1647 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648}
1649
1650// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001653 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654 var err error
1655
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001656 // populate what we know. rest comes later after mib sync
1657 dh.device.Root = false
1658 dh.device.Vendor = "OpenONU"
1659 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001660 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001661 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 if !dh.IsReconciling() {
1666 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001667 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1668 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1669 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301670 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001671 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001674 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675
Himani Chawla4d908332020-08-31 12:30:20 +05301676 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001677 dh.ponPortNumber = dh.device.ParentPortNo
1678
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001679 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1680 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1681 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001682 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001683 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301684 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001685
1686 /*
1687 self._pon = PonPort.create(self, self._pon_port_number)
1688 self._pon.add_peer(self.parent_id, self._pon_port_number)
1689 self.logger.debug('adding-pon-port-to-agent',
1690 type=self._pon.get_port().type,
1691 admin_state=self._pon.get_port().admin_state,
1692 oper_status=self._pon.get_port().oper_status,
1693 )
1694 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001695 if !dh.IsReconciling() {
1696 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001697 var ponPortNo uint32 = 1
1698 if dh.ponPortNumber != 0 {
1699 ponPortNo = dh.ponPortNumber
1700 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001701
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001702 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001703 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001704 PortNo: ponPortNo,
1705 Label: fmt.Sprintf("pon-%d", ponPortNo),
1706 Type: voltha.Port_PON_ONU,
1707 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301708 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001709 PortNo: ponPortNo}}, // Peer port is parent's port number
1710 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001711 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001712 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001713 e.Cancel(err)
1714 return
1715 }
1716 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001718 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001719 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720}
1721
1722// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001725 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726 var err error
1727 /*
1728 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1729 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1730 return nil
1731 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001733 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734 e.Cancel(err)
1735 return
1736 }
1737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001738 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001740 // reconcilement will be continued after mib download is done
1741 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001742
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001743 /*
1744 ############################################################################
1745 # Setup Alarm handler
1746 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1747 device.serial_number)
1748 ############################################################################
1749 # Setup PM configuration for this device
1750 # Pass in ONU specific options
1751 kwargs = {
1752 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1753 'heartbeat': self.heartbeat,
1754 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1755 }
1756 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1757 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1758 self.logical_device_id, device.serial_number,
1759 grouped=True, freq_override=False, **kwargs)
1760 pm_config = self._pm_metrics.make_proto()
1761 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1762 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1763 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1764
1765 # Note, ONU ID and UNI intf set in add_uni_port method
1766 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1767 ani_ports=[self._pon])
1768
1769 # Code to Run OMCI Test Action
1770 kwargs_omci_test_action = {
1771 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1772 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1773 }
1774 serial_number = device.serial_number
1775 self._test_request = OmciTestRequest(self.core_proxy,
1776 self.omci_agent, self.device_id,
1777 AniG, serial_number,
1778 self.logical_device_id,
1779 exclusive=False,
1780 **kwargs_omci_test_action)
1781
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001782 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001783 else:
1784 self.logger.info('onu-already-activated')
1785 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001786
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001787 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001788}
1789
1790// doStateConnected get the device info and update to voltha core
1791// for comparison of the original method (not that easy to uncomment): compare here:
1792// voltha-openolt-adapter/adaptercore/device_handler.go
1793// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001795
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001796 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301797 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001798 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001799 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800}
1801
1802// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001804
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001805 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301806 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001808 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001809
1810 /*
1811 // Synchronous call to update device state - this method is run in its own go routine
1812 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1813 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001814 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 +00001815 return err
1816 }
1817 return nil
1818 */
1819}
1820
1821// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001824 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001825 var err error
1826
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001827 device := dh.device
1828 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001830 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001831 e.Cancel(err)
1832 return
1833 }
1834
1835 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001837 /*
1838 // Update the all ports state on that device to disable
1839 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001840 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001841 return er
1842 }
1843
1844 //Update the device oper state and connection status
1845 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1846 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1847 dh.device = cloned
1848
1849 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001850 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001851 return er
1852 }
1853
1854 //get the child device for the parent device
1855 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1856 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001857 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001858 return err
1859 }
1860 for _, onuDevice := range onuDevices.Items {
1861
1862 // Update onu state as down in onu adapter
1863 onuInd := oop.OnuIndication{}
1864 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001865 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001866 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1867 if er != nil {
1868 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001869 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001870 //Do not return here and continue to process other ONUs
1871 }
1872 }
1873 // * Discovered ONUs entries need to be cleared , since after OLT
1874 // is up, it starts sending discovery indications again* /
1875 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001876 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001877 return nil
1878 */
Himani Chawla4d908332020-08-31 12:30:20 +05301879 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001881 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001882}
1883
Himani Chawla6d2ae152020-09-02 13:11:20 +05301884// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001885// #################################################################################
1886
1887// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301888// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001889
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001890//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1891func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001892 dh.lockDevice.RLock()
1893 pOnuDeviceEntry := dh.pOnuOmciDevice
1894 if aWait && pOnuDeviceEntry == nil {
1895 //keep the read sema short to allow for subsequent write
1896 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001897 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001898 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1899 // so it might be needed to wait here for that event with some timeout
1900 select {
1901 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001902 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001903 return nil
1904 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001905 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001906 // if written now, we can return the written value without sema
1907 return dh.pOnuOmciDevice
1908 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909 }
mpagenko3af1f032020-06-10 08:53:41 +00001910 dh.lockDevice.RUnlock()
1911 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001912}
1913
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001914//setDeviceHandlerEntries sets the ONU device entry within the handler
1915func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1916 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001917 dh.lockDevice.Lock()
1918 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001919 dh.pOnuOmciDevice = apDeviceEntry
1920 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001921 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301922 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001923 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001924}
1925
Himani Chawla6d2ae152020-09-02 13:11:20 +05301926//addOnuDeviceEntry creates a new ONU device or returns the existing
1927func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001928 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001929
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001931 if deviceEntry == nil {
1932 /* costum_me_map in python code seems always to be None,
1933 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1934 /* also no 'clock' argument - usage open ...*/
1935 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1937 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1938 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1939 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1940 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001941 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001942 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001943 // fire deviceEntry ready event to spread to possibly waiting processing
1944 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001945 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001946 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001948 }
1949 // might be updated with some error handling !!!
1950 return nil
1951}
1952
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001954 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001955 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1956
1957 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001958
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001959 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001960 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1962 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001963 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 if !dh.IsReconciling() {
1965 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001967 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001968 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001970 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001971
khenaidoo42dcdfd2021-10-19 17:34:12 -04001972 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001974 OperStatus: voltha.OperStatus_ACTIVATING,
1975 ConnStatus: voltha.ConnectStatus_REACHABLE,
1976 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001977 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001978 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001979 }
1980 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001983
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001984 pDevEntry.MutexPersOnuConfig.RLock()
1985 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1986 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 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 +00001988 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001989 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001990 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001991 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001992 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001993 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1995 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1996 // 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 +00001997 // 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 +00001998 // so let's just try to keep it simple ...
1999 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002001 if err != nil || device == nil {
2002 //TODO: needs to handle error scenarios
2003 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
2004 return errors.New("Voltha Device not found")
2005 }
2006 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002007
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002008 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002009 return err
mpagenko3af1f032020-06-10 08:53:41 +00002010 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002011 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002012
2013 /* this might be a good time for Omci Verify message? */
2014 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002015 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002016 dh.device.Id, pDevEntry.PDevOmciCC, false,
mpagenko900ee4b2020-10-12 11:56:34 +00002017 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002018 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002019
2020 /* give the handler some time here to wait for the OMCi verification result
2021 after Timeout start and try MibUpload FSM anyway
2022 (to prevent stopping on just not supported OMCI verification from ONU) */
2023 select {
Holger Hildebrandta6ef0e82022-04-06 13:11:32 +00002024 case <-time.After(((cmn.CDefaultRetries+1)*otst.CTestRequestOmciTimeout + 1) * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002025 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002026 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002027 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002028 }
2029
2030 /* In py code it looks earlier (on activate ..)
2031 # Code to Run OMCI Test Action
2032 kwargs_omci_test_action = {
2033 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2034 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2035 }
2036 serial_number = device.serial_number
2037 self._test_request = OmciTestRequest(self.core_proxy,
2038 self.omci_agent, self.device_id,
2039 AniG, serial_number,
2040 self.logical_device_id,
2041 exclusive=False,
2042 **kwargs_omci_test_action)
2043 ...
2044 # Start test requests after a brief pause
2045 if not self._test_request_started:
2046 self._test_request_started = True
2047 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2048 reactor.callLater(tststart, self._test_request.start_collector)
2049
2050 */
2051 /* which is then: in omci_test_request.py : */
2052 /*
2053 def start_collector(self, callback=None):
2054 """
2055 Start the collection loop for an adapter if the frequency > 0
2056
2057 :param callback: (callable) Function to call to collect PM data
2058 """
2059 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2060 if callback is None:
2061 callback = self.perform_test_omci
2062
2063 if self.lc is None:
2064 self.lc = LoopingCall(callback)
2065
2066 if self.default_freq > 0:
2067 self.lc.start(interval=self.default_freq / 10)
2068
2069 def perform_test_omci(self):
2070 """
2071 Perform the initial test request
2072 """
2073 ani_g_entities = self._device.configuration.ani_g_entities
2074 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2075 is not None else None
2076 self._entity_id = ani_g_entities_ids[0]
2077 self.logger.info('perform-test', entity_class=self._entity_class,
2078 entity_id=self._entity_id)
2079 try:
2080 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2081 result = yield self._device.omci_cc.send(frame)
2082 if not result.fields['omci_message'].fields['success_code']:
2083 self.logger.info('Self-Test Submitted Successfully',
2084 code=result.fields[
2085 'omci_message'].fields['success_code'])
2086 else:
2087 raise TestFailure('Test Failure: {}'.format(
2088 result.fields['omci_message'].fields['success_code']))
2089 except TimeoutError as e:
2090 self.deferred.errback(failure.Failure(e))
2091
2092 except Exception as e:
2093 self.logger.exception('perform-test-Error', e=e,
2094 class_id=self._entity_class,
2095 entity_id=self._entity_id)
2096 self.deferred.errback(failure.Failure(e))
2097
2098 */
2099
2100 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002101 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002102
mpagenko1cc3cb42020-07-27 15:24:38 +00002103 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2104 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2105 * 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 +05302106 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002107 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002108 //call MibUploadFSM - transition up to state UlStInSync
2109 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002110 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002111 if pMibUlFsm.Is(mib.UlStDisabled) {
2112 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2113 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2114 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302115 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002116 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302117 //Determine ONU status and start/re-start MIB Synchronization tasks
2118 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119 if pDevEntry.IsNewOnu() {
2120 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2121 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2122 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002123 }
Himani Chawla4d908332020-08-31 12:30:20 +05302124 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002125 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2126 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2127 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302128 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002129 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002130 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002131 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002133 "device-id": dh.DeviceID})
2134 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002135 }
2136 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002137 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2138 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002139 }
2140 return nil
2141}
2142
Holger Hildebrandt68854a82022-09-05 07:00:21 +00002143func (dh *deviceHandler) UpdateInterface(ctx context.Context) error {
mpagenko3af1f032020-06-10 08:53:41 +00002144 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002145 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002146 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2147 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002148
mpagenko900ee4b2020-10-12 11:56:34 +00002149 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2150 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2151 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002152 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002154 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002155 // abort: system behavior is just unstable ...
2156 return err
2157 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002158 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 _ = 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 +00002160
2161 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002162 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002164 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002165 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2166 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002167 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002168 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002169
2170 //TODO!!! remove existing traffic profiles
2171 /* from py code, if TP's exist, remove them - not yet implemented
2172 self._tp = dict()
2173 # Let TP download happen again
2174 for uni_id in self._tp_service_specific_task:
2175 self._tp_service_specific_task[uni_id].clear()
2176 for uni_id in self._tech_profile_download_done:
2177 self._tech_profile_download_done[uni_id].clear()
2178 */
2179
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002180 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002181
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002183
mpagenkoe4782082021-11-25 12:04:26 +00002184 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002185 // abort: system behavior is just unstable ...
2186 return err
2187 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002189 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002190 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002192 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2193 OperStatus: voltha.OperStatus_DISCOVERED,
2194 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002195 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002198 // abort: system behavior is just unstable ...
2199 return err
2200 }
2201 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002203 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002204 return nil
2205}
2206
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002207func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002208 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2209 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2210 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2211 // and using the stop/reset event should never harm
Holger Hildebrandt12609a12022-03-25 13:23:25 +00002212 logger.Debugw(ctx, "resetFsms entered", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002213
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002214 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002215 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2217 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002218 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002219 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002220 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002221 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002222 pDevEntry.MutexOnuImageStatus.RLock()
2223 if pDevEntry.POnuImageStatus != nil {
2224 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002225 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002227
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002228 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002229 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002230 }
2231 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002232 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002233 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002234 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002235 }
mpagenko101ac942021-11-16 15:01:29 +00002236 //stop any deviceHandler reconcile processing (if running)
2237 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002238 //port lock/unlock FSM's may be active
2239 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002240 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002241 }
2242 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002244 }
2245 //techProfile related PonAniConfigFsm FSM may be active
2246 if dh.pOnuTP != nil {
2247 // should always be the case here
2248 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002249 if dh.pOnuTP.PAniConfigFsm != nil {
2250 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2251 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002252 }
mpagenko900ee4b2020-10-12 11:56:34 +00002253 }
2254 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002255 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002256 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002258 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002259 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002260 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002261 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002262 } else {
2263 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002264 }
2265 }
2266 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002267 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002268 // Stop collector routine
2269 dh.stopCollector <- true
2270 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302272 dh.stopAlarmManager <- true
2273 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002274 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002276 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302277
Girish Gowdrae95687a2021-09-08 16:30:58 -07002278 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2279
mpagenko80622a52021-02-09 16:53:23 +00002280 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002282 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002283 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002284 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002285 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002286 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002287 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2288 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2289 // (even though it may also run into direct cancellation, a bit hard to verify here)
2290 // so don't set 'dh.upgradeCanceled = true' here!
2291 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2292 }
mpagenko38662d02021-08-11 09:45:19 +00002293 }
mpagenko80622a52021-02-09 16:53:23 +00002294
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002295 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002296 return nil
2297}
2298
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2300 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 +05302301
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002302 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002303 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002304 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002306 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002307 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002308 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002309
mpagenkoa40e99a2020-11-17 13:50:39 +00002310 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2311 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2312 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2313 * disable/enable toggling here to allow traffic
2314 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2315 * like the py comment says:
2316 * # start by locking all the unis till mib sync and initial mib is downloaded
2317 * # this way we can capture the port down/up events when we are ready
2318 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302319
mpagenkoa40e99a2020-11-17 13:50:39 +00002320 // Init Uni Ports to Admin locked state
2321 // *** should generate UniLockStateDone event *****
2322 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002323 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002324 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002327 }
2328}
2329
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2331 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302332 /* Mib download procedure -
2333 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2334 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002336 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002337 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002338 return
2339 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302341 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 if pMibDlFsm.Is(mib.DlStDisabled) {
2343 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2344 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 +05302345 // maybe try a FSM reset and then again ... - TODO!!!
2346 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002347 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302348 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2350 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302351 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002352 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302353 //Begin MIB data download (running autonomously)
2354 }
2355 }
2356 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002357 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002358 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 // maybe try a FSM reset and then again ... - TODO!!!
2360 }
2361 /***** Mib download started */
2362 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302364 }
2365}
2366
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002367func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2368 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002369 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
2370 if pDevEntry == nil {
2371 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
2372 return
2373 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374 if !dh.IsReconciling() {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002375 logger.Debugw(ctx, "call DeviceUpdate and DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002377 // update device info in core
2378 pDevEntry.MutexPersOnuConfig.RLock()
2379 dh.device.Vendor = pDevEntry.SOnuPersistentData.PersVendorID
2380 dh.device.VendorId = pDevEntry.SOnuPersistentData.PersVendorID
2381 dh.device.Model = pDevEntry.SOnuPersistentData.PersVersion
2382 pDevEntry.MutexPersOnuConfig.RUnlock()
2383 dh.logicalDeviceID = dh.DeviceID
2384 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
2385 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
2386 }
2387 // update device state in core
mpagenko15ff4a52021-03-02 10:09:20 +00002388 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2389 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2390 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2391 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002392 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002394 ConnStatus: voltha.ConnectStatus_REACHABLE,
2395 OperStatus: voltha.OperStatus_ACTIVE,
2396 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302397 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302399 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002400 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 }
2402 } else {
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002403 logger.Debugw(ctx, "reconciling - don't notify core about updated device info and DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002404 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302405 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002406 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002407
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 if !dh.GetCollectorIsRunning() {
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002409 var waitForOmciProcessor sync.WaitGroup
2410 waitForOmciProcessor.Add(1)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002411 // Start PM collector routine
Girish Gowdraf7d82d02022-04-26 16:18:35 -07002412 go dh.StartCollector(ctx, &waitForOmciProcessor)
2413 waitForOmciProcessor.Wait()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002414 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 if !dh.GetAlarmManagerIsRunning(ctx) {
2416 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002417 }
2418
Girish Gowdrae95687a2021-09-08 16:30:58 -07002419 // Start flow handler routines per UNI
2420 for _, uniPort := range dh.uniEntityMap {
2421 // only if this port was enabled for use by the operator at startup
2422 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2423 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2424 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2425 }
2426 }
2427 }
2428
Girish Gowdrae0140f02021-02-02 16:55:09 -08002429 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002430 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002431 // There is no way we should be landing here, but if we do then
2432 // there is nothing much we can do about this other than log error
2433 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2434 }
2435
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002436 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002437
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002438 pDevEntry.MutexPersOnuConfig.RLock()
2439 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2440 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002441 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002442 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002443 dh.mutexForDisableDeviceRequested.Lock()
2444 dh.disableDeviceRequested = true
2445 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002446 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002447 // reconcilement will be continued after ani config is done
2448 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002450 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002451 dh.mutexForDisableDeviceRequested.RLock()
2452 if !dh.disableDeviceRequested {
2453 if dh.pUnlockStateFsm == nil {
2454 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2455 } else { //UnlockStateFSM already init
2456 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2457 dh.runUniLockFsm(ctx, false)
2458 }
2459 dh.mutexForDisableDeviceRequested.RUnlock()
2460 } else {
2461 dh.mutexForDisableDeviceRequested.RUnlock()
2462 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002463 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302464 }
2465}
2466
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2468 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302469
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 if !dh.IsReconciling() {
2471 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002472 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2474 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002475 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002476 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002477 return
2478 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002479 pDevEntry.MutexPersOnuConfig.Lock()
2480 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2481 pDevEntry.MutexPersOnuConfig.Unlock()
2482 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002484 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002485 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302486 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 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 +00002488 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002489 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002490 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302491 }
2492}
2493
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002495 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002497
mpagenko44bd8362021-11-15 11:40:05 +00002498 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002499 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002500 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002501 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002502 OperStatus: voltha.OperStatus_UNKNOWN,
2503 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002504 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002505 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002506 }
2507
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002509 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002510 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002511
2512 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002513 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002514
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002516 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002518 return
2519 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 pDevEntry.MutexPersOnuConfig.Lock()
2521 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2522 pDevEntry.MutexPersOnuConfig.Unlock()
2523 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526 }
mpagenko900ee4b2020-10-12 11:56:34 +00002527}
2528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002529func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002532 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002533 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002534 ConnStatus: voltha.ConnectStatus_REACHABLE,
2535 OperStatus: voltha.OperStatus_ACTIVE,
2536 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002537 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002539 }
2540
dbainbri4d3a0dc2020-12-02 00:33:42 +00002541 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002543 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002544 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002545
2546 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002548
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002549 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002550 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002551 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002552 return
2553 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 pDevEntry.MutexPersOnuConfig.Lock()
2555 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2556 pDevEntry.MutexPersOnuConfig.Unlock()
2557 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002558 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002560 }
mpagenko900ee4b2020-10-12 11:56:34 +00002561}
2562
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002563func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2564 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2565 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002566 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002567 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002568 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002569 OperStatus: voltha.OperStatus_FAILED,
2570 }); err != nil {
2571 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2572 }
2573}
2574
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2576 if devEvent == cmn.OmciAniConfigDone {
2577 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002578 // attention: the device reason update is done based on ONU-UNI-Port related activity
2579 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002581 // 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 +00002582 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302583 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002585 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2586 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2587 dh.mutexReconcilingFirstPassFlag.Lock()
2588 if dh.reconcilingFirstPass {
2589 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2590 dh.reconcilingFirstPass = false
2591 go dh.ReconcileDeviceFlowConfig(ctx)
2592 }
2593 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002594 }
2595 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002597 // attention: the device reason update is done based on ONU-UNI-Port related activity
2598 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002599 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002600 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2601 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002602 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002603 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302604}
2605
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002608 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302609 // attention: the device reason update is done based on ONU-UNI-Port related activity
2610 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002612 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2613 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002614 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002615 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002616 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002617 }
2618 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002619 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002620 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002621 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002622 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302623 }
mpagenkof1fc3862021-02-16 10:09:52 +00002624
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002626 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002627 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002628 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002630 }
2631 } else {
2632 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002634 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302635}
2636
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002637//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2638func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302639 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002640 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002641 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002643 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002644 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002645 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002647 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002649 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002651 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002652 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002653 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002655 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002657 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002658 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002659 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002660 case cmn.UniEnableStateFailed:
2661 {
2662 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2663 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002664 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002665 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002667 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002669 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002670 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002671 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002672 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002673 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002674 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002675 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002676 default:
2677 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002678 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 }
2680 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002681}
2682
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002684 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002685 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302686 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002687 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002688 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002689 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302690 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002691 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002692 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002693 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 +00002694 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002695 //store UniPort with the System-PortNumber key
2696 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002698 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002699 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002700 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002701 } //error logging already within UniPort method
2702 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002704 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002705 }
2706 }
2707}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002708
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2710 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002711 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002712 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002713 return
2714 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002715 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002717 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2718 for _, mgmtEntityID := range pptpInstKeys {
2719 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002721 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2722 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002723 }
2724 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002726 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002728 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2729 for _, mgmtEntityID := range veipInstKeys {
2730 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002731 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002732 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2733 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002734 }
2735 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002736 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002737 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002739 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2740 for _, mgmtEntityID := range potsInstKeys {
2741 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002743 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2744 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002745 }
2746 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002748 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002749 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002751 return
2752 }
2753
mpagenko2c3f6c52021-11-23 11:22:10 +00002754 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2755 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2756 // 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 -07002757 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2758 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2759 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002760 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2761 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002762 for i := 0; i < int(uniCnt); i++ {
2763 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00002764 dh.stopFlowMonitoringRoutine[i] = make(chan bool, 1)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002765 }
2766}
2767
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002768// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2769func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002770 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302771 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002772 // with following remark:
2773 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2774 // # load on the core
2775
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002776 // 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 +00002777
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002778 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002779 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2781 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2782 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2783 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002784 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002785 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002786 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002788 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 PortNo: port.PortNo,
2790 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002791 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002792 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 -04002793 }
2794 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002795 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002796 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002797 }
mpagenko3af1f032020-06-10 08:53:41 +00002798 }
2799 }
2800}
2801
2802// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2804 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002805 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2806 for uniNo, uniPort := range dh.uniEntityMap {
2807 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002808
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002809 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2810 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2811 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2812 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002813 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002814 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002815 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002816 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002817 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002818 PortNo: port.PortNo,
2819 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002820 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 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 -04002822 }
2823 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002824 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002825 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002826 }
2827
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002828 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002829 }
2830}
2831
2832// ONU_Active/Inactive announcement on system KAFKA bus
2833// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002834func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002835 var de voltha.DeviceEvent
2836 eventContext := make(map[string]string)
2837 //Populating event context
2838 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002839 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002840 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002842 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002843 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 +00002844 }
2845 oltSerialNumber := parentDevice.SerialNumber
2846
2847 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2848 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2849 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302850 eventContext["olt-serial-number"] = oltSerialNumber
2851 eventContext["device-id"] = aDeviceID
2852 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002853 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2855 deviceEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt3d3c2c52022-06-08 13:25:43 +00002856 eventContext["vendor-id"] = deviceEntry.SOnuPersistentData.PersVendorID
2857 eventContext["model"] = deviceEntry.SOnuPersistentData.PersVersion
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2859 deviceEntry.MutexPersOnuConfig.RUnlock()
2860 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002862 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2863 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2864 } else {
2865 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2866 log.Fields{"device-id": aDeviceID})
2867 return
2868 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002869
2870 /* Populating device event body */
2871 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302872 de.ResourceId = aDeviceID
2873 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002874 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2875 de.Description = fmt.Sprintf("%s Event - %s - %s",
2876 cEventObjectType, cOnuActivatedEvent, "Raised")
2877 } else {
2878 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2879 de.Description = fmt.Sprintf("%s Event - %s - %s",
2880 cEventObjectType, cOnuActivatedEvent, "Cleared")
2881 }
2882 /* Send event to KAFKA */
kesavand510a31c2022-03-16 17:12:12 +05302883 if err := dh.EventProxy.SendDeviceEventWithKey(ctx, &de, equipment, pon, raisedTs, aDeviceID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302885 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002886 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302888 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002889}
2890
Himani Chawla4d908332020-08-31 12:30:20 +05302891// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2893 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002894 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302895 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002896 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002897 sFsmName = "LockStateFSM"
2898 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002899 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002900 sFsmName = "UnLockStateFSM"
2901 }
mpagenko3af1f032020-06-10 08:53:41 +00002902
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002904 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002906 return
2907 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002909 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302910 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002911 dh.pLockStateFsm = pLSFsm
2912 } else {
2913 dh.pUnlockStateFsm = pLSFsm
2914 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002916 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002917 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002918 }
2919}
2920
2921// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002923 /* Uni Port lock/unlock procedure -
2924 ***** should run via 'adminDone' state and generate the argument requested event *****
2925 */
2926 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302927 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002929 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2930 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2932 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002933 }
2934 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002936 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2937 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2939 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002940 }
2941 }
2942 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2944 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002945 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002946 // maybe try a FSM reset and then again ... - TODO!!!
2947 } else {
2948 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002949 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002950 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002951 }
2952 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002953 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002955 // maybe try a FSM reset and then again ... - TODO!!!
2956 }
2957 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002959 // maybe try a FSM reset and then again ... - TODO!!!
2960 }
2961}
2962
mpagenko80622a52021-02-09 16:53:23 +00002963// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002964// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002965func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002967 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002969 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002971 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002972 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002974 sFsmName, chUpgradeFsm)
2975 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002977 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2979 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002980 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002981 // maybe try a FSM reset and then again ... - TODO!!!
2982 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2983 }
mpagenko59862f02021-10-11 08:53:18 +00002984 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002985 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2986 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002987 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2988 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002989 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002991 } else {
2992 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002993 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002994 // maybe try a FSM reset and then again ... - TODO!!!
2995 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2996 }
2997 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"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 internal FSM could not be created for device-id: %s", dh.device.Id))
3001 }
3002 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003003 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003004 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
3005 }
3006 return nil
3007}
3008
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
3010func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00003011 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003012 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00003013 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00003014 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
3015 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00003016 dh.pLastUpgradeImageState = apImageState
3017 dh.lockUpgradeFsm.Unlock()
3018 //signal upgradeFsm removed using non-blocking channel send
3019 select {
3020 case dh.upgradeFsmChan <- struct{}{}:
3021 default:
3022 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003023 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003024 }
mpagenko80622a52021-02-09 16:53:23 +00003025}
3026
mpagenko15ff4a52021-03-02 10:09:20 +00003027// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3028func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003029 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003030 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003032 return
3033 }
3034
3035 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003036 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003037 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003038 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3039 dh.lockUpgradeFsm.RUnlock()
3040 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3041 return
3042 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003044 if pUpgradeStatemachine != nil {
3045 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3046 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047 UpgradeState := pUpgradeStatemachine.Current()
3048 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3049 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3050 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003051 // 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 +00003052 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003053 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3054 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003055 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003056 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003058 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3059 dh.upgradeCanceled = true
3060 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3061 }
mpagenko15ff4a52021-03-02 10:09:20 +00003062 return
3063 }
mpagenko59862f02021-10-11 08:53:18 +00003064 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3066 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003067 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003069 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3070 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003071 return
3072 }
3073 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003074 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003075 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003076 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3077 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003078 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3079 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003080 return
3081 }
3082 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003084 }
3085 } else {
3086 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 +00003087 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003088 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3089 dh.upgradeCanceled = true
3090 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3091 }
mpagenko1f8e8822021-06-25 14:10:21 +00003092 }
mpagenko15ff4a52021-03-02 10:09:20 +00003093 return
3094 }
mpagenko59862f02021-10-11 08:53:18 +00003095 dh.lockUpgradeFsm.RUnlock()
3096 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3097 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003098 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3099 dh.upgradeCanceled = true
3100 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3101 }
mpagenko59862f02021-10-11 08:53:18 +00003102 return
3103 }
3104 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3105 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3106 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3107 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3108 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3109 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3110 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003111 }
mpagenko15ff4a52021-03-02 10:09:20 +00003112 }
3113 }
3114 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003115 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003116 }
mpagenko59862f02021-10-11 08:53:18 +00003117 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003118}
3119
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120//SetBackend provides a DB backend for the specified path on the existing KV client
3121func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003122
3123 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003124 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003125 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003126 kvbackend := &db.Backend{
3127 Client: dh.pOpenOnuAc.kvClient,
3128 StoreType: dh.pOpenOnuAc.KVStoreType,
3129 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003130 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003131 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3132 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003133
mpagenkoaf801632020-07-03 10:00:42 +00003134 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003135}
khenaidoo7d3c5582021-08-11 18:09:44 -04003136func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303137 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003138
mpagenkodff5dda2020-08-28 11:52:01 +00003139 for _, field := range flow.GetOfbFields(apFlowItem) {
3140 switch field.Type {
3141 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3142 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003143 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003144 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3145 }
mpagenko01e726e2020-10-23 09:45:29 +00003146 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003147 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3148 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303149 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003150 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303151 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3152 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003153 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3154 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003155 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003156 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303157 return
mpagenkodff5dda2020-08-28 11:52:01 +00003158 }
3159 }
mpagenko01e726e2020-10-23 09:45:29 +00003160 */
mpagenkodff5dda2020-08-28 11:52:01 +00003161 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3162 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303163 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003164 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303165 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003166 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303167 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003168 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003169 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303170 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003171 }
3172 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3173 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303174 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003175 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303176 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003177 }
3178 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3179 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003181 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3182 }
3183 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
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-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3187 }
3188 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3189 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003191 "IPv4-DST": field.GetIpv4Dst()})
3192 }
3193 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3194 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003195 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003196 "IPv4-SRC": field.GetIpv4Src()})
3197 }
3198 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
3202 }
3203 /*
3204 default:
3205 {
3206 //all other entires ignored
3207 }
3208 */
3209 }
3210 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303211}
mpagenkodff5dda2020-08-28 11:52:01 +00003212
khenaidoo7d3c5582021-08-11 18:09:44 -04003213func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003214 for _, action := range flow.GetActions(apFlowItem) {
3215 switch action.Type {
3216 /* not used:
3217 case of.OfpActionType_OFPAT_OUTPUT:
3218 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003220 "Output": action.GetOutput()})
3221 }
3222 */
3223 case of.OfpActionType_OFPAT_PUSH_VLAN:
3224 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003225 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003226 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3227 }
3228 case of.OfpActionType_OFPAT_SET_FIELD:
3229 {
3230 pActionSetField := action.GetSetField()
3231 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003233 "OxcmClass": pActionSetField.Field.OxmClass})
3234 }
3235 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303236 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303238 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003239 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303240 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003241 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303242 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003243 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003244 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003245 "Type": pActionSetField.Field.GetOfbField().Type})
3246 }
3247 }
3248 /*
3249 default:
3250 {
3251 //all other entires ignored
3252 }
3253 */
3254 }
3255 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303256}
3257
3258//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003259func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003260 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303261 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3262 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303263 var loSetPcp uint8
3264 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303265 var loIPProto uint32
3266 /* the TechProfileId is part of the flow Metadata - compare also comment within
3267 * OLT-Adapter:openolt_flowmgr.go
3268 * Metadata 8 bytes:
3269 * Most Significant 2 Bytes = Inner VLAN
3270 * Next 2 Bytes = Tech Profile ID(TPID)
3271 * Least Significant 4 Bytes = Port ID
3272 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3273 * subscriber related flows.
3274 */
3275
dbainbri4d3a0dc2020-12-02 00:33:42 +00003276 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303277 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003278 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003280 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303281 }
mpagenko551a4d42020-12-08 18:09:20 +00003282 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003283 loCookie := apFlowItem.GetCookie()
3284 loCookieSlice := []uint64{loCookie}
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303285 loInnerCvlan := flow.GetInnerTagFromWriteMetaData(ctx, metadata)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003286 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303287 "TechProf-Id": loTpID, "cookie": loCookie, "innerCvlan": loInnerCvlan})
Himani Chawla26e555c2020-08-31 12:30:20 +05303288
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303289 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003290 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303291 if loIPProto == 2 {
3292 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3293 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003294 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003295 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303296 return nil
3297 }
mpagenko01e726e2020-10-23 09:45:29 +00003298 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003299 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003300
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303301 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) &&
3302 loInnerCvlan == uint16(of.OfpVlanId_OFPVID_NONE) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003303 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003304 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003305 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3306 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3307 //TODO!!: Use DeviceId within the error response to rwCore
3308 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003309 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003310 }
3311 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003312 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003313 loSetVlan = loMatchVlan //both 'transparent' (copy any)
Abhilash Laxmeshwarf15a0d02022-08-08 11:09:32 +05303314 } else if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) &&
3315 loInnerCvlan != uint16(of.OfpVlanId_OFPVID_NONE) {
3316 loSetVlan = loMatchVlan
3317 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 +00003318 } else {
3319 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3320 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3321 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303322 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003323 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003324 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003325 }
mpagenko9a304ea2020-12-16 15:54:01 +00003326
khenaidoo42dcdfd2021-10-19 17:34:12 -04003327 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003328 if apFlowMetaData != nil {
3329 meter = apFlowMetaData.Meters[0]
3330 }
mpagenkobc4170a2021-08-17 16:42:10 +00003331 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3332 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3333 // when different rules are requested concurrently for the same uni
3334 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3335 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3336 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003337 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3338 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003339 //SetUniFlowParams() may block on some rule that is suspended-to-add
3340 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003341 // Also the error is returned to caller via response channel
3342 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303343 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003344 dh.lockVlanConfig.RUnlock()
3345 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003346 return
mpagenkodff5dda2020-08-28 11:52:01 +00003347 }
mpagenkobc4170a2021-08-17 16:42:10 +00003348 dh.lockVlanConfig.RUnlock()
3349 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003350 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303351 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, loInnerCvlan, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003352 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003353 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003354 if err != nil {
3355 *respChan <- err
3356 }
mpagenko01e726e2020-10-23 09:45:29 +00003357}
3358
3359//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003360func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003361 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3362 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3363 //no extra check is done on the rule parameters
3364 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3365 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3366 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3367 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003368 // - 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 +00003369 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003371
3372 /* TT related temporary workaround - should not be needed anymore
3373 for _, field := range flow.GetOfbFields(apFlowItem) {
3374 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3375 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003376 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003377 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3378 if loIPProto == 2 {
3379 // 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 +00003380 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003381 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003382 return nil
3383 }
3384 }
3385 } //for all OfbFields
3386 */
3387
mpagenko9a304ea2020-12-16 15:54:01 +00003388 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003389 dh.lockVlanConfig.RLock()
3390 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3392 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003393 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3394 return
mpagenko01e726e2020-10-23 09:45:29 +00003395 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003396 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003397 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003398 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003399 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003400 // Push response on the response channel
3401 if respChan != nil {
3402 // 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
3403 select {
3404 case *respChan <- nil:
3405 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3406 default:
3407 }
3408 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003409 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003410}
3411
Himani Chawla26e555c2020-08-31 12:30:20 +05303412// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003413// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003414// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003415func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303416 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 +00003417 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003418
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003419 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003420 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003421 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3422 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003423 }
3424
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3426 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05303427 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003428 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003429 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3430 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003431 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3432 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003433 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003434 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3435 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003436 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3437 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003439 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303440 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003441 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3443 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003444 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003445 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3447 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003448 }
3449 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003450 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003451 "device-id": dh.DeviceID})
3452 return fmt.Errorf("uniVlanConfigFsm invalid 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 could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003456 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3457 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003458 }
3459 return nil
3460}
3461
mpagenkofc4f56e2020-11-04 17:17:49 +00003462//VerifyVlanConfigRequest checks on existence of a given uniPort
3463// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003464func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003465 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003466 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003467 for _, uniPort := range dh.uniEntityMap {
3468 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003470 pCurrentUniPort = uniPort
3471 break //found - end search loop
3472 }
3473 }
3474 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003475 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003477 return
3478 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003480}
3481
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003482//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3483func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003484 //TODO!! verify and start pending flow configuration
3485 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3486 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003487
3488 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003490 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003491 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003492 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003493 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003494 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003495 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003496 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3497 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003498 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003500 } else {
3501 /***** UniVlanConfigFsm continued */
3502 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003503 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3504 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003505 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3507 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003508 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003509 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003510 } else {
3511 /***** UniVlanConfigFsm continued */
3512 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3514 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003515 }
mpagenkodff5dda2020-08-28 11:52:01 +00003516 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003517 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3519 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003520 }
3521 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003522 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 +00003523 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3524 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003525 }
3526 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003527 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003528 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003529 }
mpagenkof1fc3862021-02-16 10:09:52 +00003530 } else {
3531 dh.lockVlanConfig.RUnlock()
3532 }
mpagenkodff5dda2020-08-28 11:52:01 +00003533}
3534
3535//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3536// 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 +00003537func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003538 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003540 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003541 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003542 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003543 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003544}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003545
mpagenkof1fc3862021-02-16 10:09:52 +00003546//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003547func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003548 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3549 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3550 // obviously then parallel processing on the cancel must be avoided
3551 // deadline context to ensure completion of background routines waited for
3552 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3553 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3554 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003556 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003557 var wg sync.WaitGroup
3558 wg.Add(1) // for the 1 go routine to finish
3559
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003560 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003561 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3562
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003563 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003564}
3565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003566//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003567//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003568func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3569 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003570
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003571 if dh.IsReconciling() {
3572 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003573 return nil
3574 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003575 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003576
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003577 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003578 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3580 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003581 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003582 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003583
mpagenkof1fc3862021-02-16 10:09:52 +00003584 if aWriteToKvStore {
3585 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3586 }
3587 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003588}
3589
dbainbri4d3a0dc2020-12-02 00:33:42 +00003590func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003591 defer cancel() //ensure termination of context (may be pro forma)
3592 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003593 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003595}
3596
mpagenkoe4782082021-11-25 12:04:26 +00003597//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3598// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3599func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3600 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3601 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3602 dh.mutexDeviceReason.Lock()
3603 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003604 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003605 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003606 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 DeviceId: dh.DeviceID,
3608 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003609 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003610 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003612 return err
3613 }
mpagenkoe4782082021-11-25 12:04:26 +00003614 } else {
3615 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 +00003616 }
mpagenkoe4782082021-11-25 12:04:26 +00003617 dh.deviceReason = deviceReason
3618 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3619 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003620 return nil
3621}
3622
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003623func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3624 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003625 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003626 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3627 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003628 }
mpagenkof1fc3862021-02-16 10:09:52 +00003629 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003630}
3631
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003632// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003633// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003634func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3635 dh.lockDevice.RLock()
3636 defer dh.lockDevice.RUnlock()
3637 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003638 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003639 }
3640 return 0, errors.New("error-fetching-uni-port")
3641}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003642
3643// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003644func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3645 var errorsList []error
3646 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 -08003647
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003648 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3649 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3650 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3651
3652 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3653 // successfully.
3654 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3655 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3656 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003657 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 -08003658 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003659 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003661 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003662}
3663
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003664func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3665 var err error
3666 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003667 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003668
3669 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003670 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003671 errorsList = append(errorsList, err)
3672 }
3673 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003674 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003675
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 return errorsList
3677}
3678
3679func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3680 var err error
3681 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003682 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003683 // Check if group metric related config is updated
3684 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003685 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3686 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3687 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003688
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003689 if ok && m.Frequency != v.GroupFreq {
3690 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003691 errorsList = append(errorsList, err)
3692 }
3693 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003694 if ok && m.Enabled != v.Enabled {
3695 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003696 errorsList = append(errorsList, err)
3697 }
3698 }
3699 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003700 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003701 return errorsList
3702}
3703
3704func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3705 var err error
3706 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003707 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003708 // Check if standalone metric related config is updated
3709 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003710 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3711 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3712 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003713
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003714 if ok && m.Frequency != v.SampleFreq {
3715 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003716 errorsList = append(errorsList, err)
3717 }
3718 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003719 if ok && m.Enabled != v.Enabled {
3720 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003721 errorsList = append(errorsList, err)
3722 }
3723 }
3724 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003725 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003726 return errorsList
3727}
3728
3729// nolint: gocyclo
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003730func (dh *deviceHandler) StartCollector(ctx context.Context, waitForOmciProcessor *sync.WaitGroup) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003731 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003732
3733 // Start routine to process OMCI GET Responses
Girish Gowdraf7d82d02022-04-26 16:18:35 -07003734 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx, waitForOmciProcessor)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303735 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003736 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003737 // Initialize the next metric collection time.
3738 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3739 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003740 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003741 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003742 for {
3743 select {
3744 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003745 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003746 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003747 // Stop the L2 PM FSM
3748 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003749 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3750 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3751 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003752 }
3753 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003754 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003755 }
3756 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003757 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3758 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003759 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003760 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3761 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003762 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003763
Girish Gowdrae09a6202021-01-12 18:10:59 -08003764 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3766 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3767 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3768 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3769 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003770 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003771 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003772 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003773 } else {
3774 if dh.pmConfigs.Grouped { // metrics are managed as a group
3775 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003777
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003778 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3779 // 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 -08003780 // 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 +00003781 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3782 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003783 }
3784 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003785 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3786 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3787 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3788 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003789 }
3790 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003792
3793 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003794 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3795 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3796 // 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 -08003797 // 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 +00003798 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3799 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003800 }
3801 }
3802 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003803 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3804 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3805 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3806 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003807 }
3808 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003809 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003810 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003811 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003812 } */
3813 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003814 }
3815 }
3816}
kesavandfdf77632021-01-26 23:40:33 -05003817
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003818func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003819
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003820 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3821 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003822}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003823
Himani Chawla43f95ff2021-06-03 00:24:12 +05303824func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3825 if dh.pOnuMetricsMgr == nil {
3826 return &extension.SingleGetValueResponse{
3827 Response: &extension.GetValueResponse{
3828 Status: extension.GetValueResponse_ERROR,
3829 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3830 },
3831 }
3832 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303833 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303834 return resp
3835}
3836
Holger Hildebrandt66af5ce2022-09-07 13:38:02 +00003837func (dh *deviceHandler) getOnuOMCIStats(ctx context.Context) (*extension.SingleGetValueResponse, error) {
3838
3839 var err error
3840 var pDevOmciCC *cmn.OmciCC
3841 if dh.pOnuOmciDevice == nil {
3842 logger.Errorw(ctx, "No valid DeviceEntry", log.Fields{"device-id": dh.DeviceID})
3843 err = fmt.Errorf("no-valid-DeviceEntry-%s", dh.DeviceID)
3844 } else {
3845 pDevOmciCC = dh.pOnuOmciDevice.GetDevOmciCC()
3846 if pDevOmciCC == nil {
3847 logger.Errorw(ctx, "No valid DeviceOmciCCEntry", log.Fields{"device-id": dh.DeviceID})
3848 err = fmt.Errorf("no-valid-DeviceOmciCCEntry-%s", dh.DeviceID)
3849 }
3850 }
3851 if err != nil {
3852 return &extension.SingleGetValueResponse{
3853 Response: &extension.GetValueResponse{
3854 Status: extension.GetValueResponse_ERROR,
3855 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3856 },
3857 },
3858 err
3859 }
3860 return pDevOmciCC.GetOmciCounters(), nil
3861}
3862
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003863func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3864 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003865 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003866 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003867 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003868}
3869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003871 var pAdapterFsm *cmn.AdapterFsm
3872 //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 +00003873 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003875 {
mpagenkofbf577d2021-10-12 11:44:33 +00003876 if dh.pOnuOmciDevice != nil {
3877 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3878 } else {
3879 return true //FSM not active - so there is no activity on omci
3880 }
mpagenkof1fc3862021-02-16 10:09:52 +00003881 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003882 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003883 {
mpagenkofbf577d2021-10-12 11:44:33 +00003884 if dh.pOnuOmciDevice != nil {
3885 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3886 } else {
3887 return true //FSM not active - so there is no activity on omci
3888 }
mpagenkof1fc3862021-02-16 10:09:52 +00003889 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003890 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003891 {
mpagenkofbf577d2021-10-12 11:44:33 +00003892 if dh.pLockStateFsm != nil {
3893 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3894 } else {
3895 return true //FSM not active - so there is no activity on omci
3896 }
mpagenkof1fc3862021-02-16 10:09:52 +00003897 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003898 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003899 {
mpagenkofbf577d2021-10-12 11:44:33 +00003900 if dh.pUnlockStateFsm != nil {
3901 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3902 } else {
3903 return true //FSM not active - so there is no activity on omci
3904 }
mpagenkof1fc3862021-02-16 10:09:52 +00003905 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003906 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003907 {
mpagenkofbf577d2021-10-12 11:44:33 +00003908 if dh.pOnuMetricsMgr != nil {
3909 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003910 } else {
3911 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003912 }
3913 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003914 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003915 {
3916 dh.lockUpgradeFsm.RLock()
3917 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003918 if dh.pOnuUpradeFsm != nil {
3919 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3920 } else {
3921 return true //FSM not active - so there is no activity on omci
3922 }
mpagenko80622a52021-02-09 16:53:23 +00003923 }
mpagenkof1fc3862021-02-16 10:09:52 +00003924 default:
3925 {
3926 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003927 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003928 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003929 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003930 }
mpagenkofbf577d2021-10-12 11:44:33 +00003931 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3932 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3933 }
3934 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003935}
3936
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003937func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3938 for _, v := range dh.pOnuTP.PAniConfigFsm {
3939 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003940 return false
3941 }
3942 }
3943 return true
3944}
3945
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003946func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003947 dh.lockVlanConfig.RLock()
3948 defer dh.lockVlanConfig.RUnlock()
3949 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003950 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003951 return false
3952 }
3953 }
3954 return true //FSM not active - so there is no activity on omci
3955}
3956
3957func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3958 dh.lockVlanConfig.RLock()
3959 defer dh.lockVlanConfig.RUnlock()
3960 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003961 if v.PAdaptFsm.PFsm != nil {
3962 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003963 return true //there is at least one VLAN FSM with some active configuration
3964 }
3965 }
3966 }
3967 return false //there is no VLAN FSM with some active configuration
3968}
3969
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003970func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003971 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3972 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3973 return false
3974 }
3975 }
3976 // a further check is done to identify, if at least some data traffic related configuration exists
3977 // 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])
3978 return dh.checkUserServiceExists(ctx)
3979}
3980
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003981func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003982 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3983 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003984 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003985 // TODO: fatal error reset ONU, delete deviceHandler!
3986 return
3987 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003988 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3989 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003990}
3991
3992func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3993 dh.mutexCollectorFlag.Lock()
3994 dh.collectorIsRunning = flagValue
3995 dh.mutexCollectorFlag.Unlock()
3996}
3997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003998func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003999 dh.mutexCollectorFlag.RLock()
4000 flagValue := dh.collectorIsRunning
4001 dh.mutexCollectorFlag.RUnlock()
4002 return flagValue
4003}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304004
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304005func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
4006 dh.mutextAlarmManagerFlag.Lock()
4007 dh.alarmManagerIsRunning = flagValue
4008 dh.mutextAlarmManagerFlag.Unlock()
4009}
4010
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004011func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304012 dh.mutextAlarmManagerFlag.RLock()
4013 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004014 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304015 dh.mutextAlarmManagerFlag.RUnlock()
4016 return flagValue
4017}
4018
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004019func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004020 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304021
4022 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004023 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304024 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304025 if stop := <-dh.stopAlarmManager; stop {
4026 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05304027 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05304028 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
4030 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05304031 }
Himani Chawlad3dac422021-03-13 02:31:31 +05304032 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004033 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
4034 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05304035 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05304036 }
4037}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00004038
Girish Gowdrae95687a2021-09-08 16:30:58 -07004039func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
4040 dh.mutexFlowMonitoringRoutineFlag.Lock()
4041 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004042 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004043 dh.isFlowMonitoringRoutineActive[uniID] = flag
4044}
4045
4046func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
4047 dh.mutexFlowMonitoringRoutineFlag.RLock()
4048 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
4049 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004050 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07004051 return dh.isFlowMonitoringRoutineActive[uniID]
4052}
4053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004054func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
4055 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004056
Maninder7961d722021-06-16 22:10:28 +05304057 connectStatus := voltha.ConnectStatus_UNREACHABLE
4058 operState := voltha.OperStatus_UNKNOWN
4059
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004060 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004061 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004062 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004063 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004064 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004065 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004066 logger.Debugw(ctx, "reconciling finished signal received",
4067 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4068 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4069 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4070 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4071 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4072 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4073 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4074 // However, a later refactoring of the functionality remains unaffected.
4075 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004076 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004077 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304078 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004079 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304080 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004081 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004082 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304083 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004084 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4085 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304086 operState = voltha.OperStatus_ACTIVE
4087 } else {
4088 operState = voltha.OperStatus_ACTIVATING
4089 }
4090 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004091 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4092 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4093 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304094 operState = voltha.OperStatus_DISCOVERED
4095 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004096 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004097 logger.Debugw(ctx, "Core DeviceStateUpdate",
4098 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304099 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004100 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004101 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004102 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004103 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004104 ConnStatus: connectStatus,
4105 OperStatus: operState,
4106 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304107 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004108 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304109 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004110 } else {
Maninderb5187552021-03-23 22:23:42 +05304111 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004114 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304115 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004116 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004117 } else {
4118 onuDevEntry.MutexPersOnuConfig.RLock()
4119 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4120 connectStatus = voltha.ConnectStatus_REACHABLE
4121 }
4122 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304123 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004124 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004125 }
mpagenko101ac942021-11-16 15:01:29 +00004126 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004127 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004128 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004129 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304130
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004131 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304132 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004133 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004134 } else {
4135 onuDevEntry.MutexPersOnuConfig.RLock()
4136 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4137 connectStatus = voltha.ConnectStatus_REACHABLE
4138 }
4139 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304140 }
4141
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004142 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304143
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004144 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004145 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004146 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004147 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004148 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004149
4150 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4151 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4152 } else {
4153 onuDevEntry.MutexReconciledTpInstances.Lock()
4154 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4155 onuDevEntry.MutexReconciledTpInstances.Unlock()
4156 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004157 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004158 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004159 dh.mutexReconcilingFlag.Lock()
4160 if skipOnuConfig {
4161 dh.reconciling = cSkipOnuConfigReconciling
4162 } else {
4163 dh.reconciling = cOnuConfigReconciling
4164 }
4165 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004166}
4167
mpagenko101ac942021-11-16 15:01:29 +00004168func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004169 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4170 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004171 dh.sendChReconcileFinished(success)
4172 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4173 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4174 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004175 } else {
mpagenko101ac942021-11-16 15:01:29 +00004176 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004177 }
4178}
4179
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004180func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004181 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004182 defer dh.mutexReconcilingFlag.RUnlock()
4183 return dh.reconciling != cNoReconciling
4184}
4185
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004186func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004187 dh.mutexReconcilingFlag.RLock()
4188 defer dh.mutexReconcilingFlag.RUnlock()
4189 return dh.reconciling == cSkipOnuConfigReconciling
4190}
4191
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004192func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4193 dh.mutexReconcilingFirstPassFlag.Lock()
4194 dh.reconcilingFirstPass = value
4195 dh.mutexReconcilingFirstPassFlag.Unlock()
4196}
4197
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004198func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4199 dh.mutexReconcilingReasonUpdate.Lock()
4200 dh.reconcilingReasonUpdate = value
4201 dh.mutexReconcilingReasonUpdate.Unlock()
4202}
4203
4204func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4205 dh.mutexReconcilingReasonUpdate.RLock()
4206 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4207 return dh.reconcilingReasonUpdate
4208}
4209
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004210func (dh *deviceHandler) getDeviceReason() uint8 {
4211 dh.mutexDeviceReason.RLock()
4212 value := dh.deviceReason
4213 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004214 return value
4215}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004216
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004217func (dh *deviceHandler) GetDeviceReasonString() string {
4218 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004219}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004220
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004221func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004222 dh.mutexReadyForOmciConfig.Lock()
4223 dh.readyForOmciConfig = flagValue
4224 dh.mutexReadyForOmciConfig.Unlock()
4225}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004226func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004227 dh.mutexReadyForOmciConfig.RLock()
4228 flagValue := dh.readyForOmciConfig
4229 dh.mutexReadyForOmciConfig.RUnlock()
4230 return flagValue
4231}
Maninder7961d722021-06-16 22:10:28 +05304232
4233func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004234 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304235 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004236 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304237 }
4238
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004239 logger.Debugw(ctx, "Core DeviceStateUpdate",
4240 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004241 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004242 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004243 ConnStatus: connectStatus,
4244 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4245 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304246 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004247 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304248 }
4249}
khenaidoo7d3c5582021-08-11 18:09:44 -04004250
4251/*
4252Helper functions to communicate with Core
4253*/
4254
4255func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4256 cClient, err := dh.coreClient.GetCoreServiceClient()
4257 if err != nil || cClient == nil {
4258 return nil, err
4259 }
4260 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4261 defer cancel()
4262 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4263 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4264}
4265
khenaidoo42dcdfd2021-10-19 17:34:12 -04004266func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004267 cClient, err := dh.coreClient.GetCoreServiceClient()
4268 if err != nil || cClient == nil {
4269 return err
4270 }
4271 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4272 defer cancel()
4273 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004274 logger.Debugw(subCtx, "device-updated-in-core",
4275 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004276 return err
4277}
4278
4279func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4280 cClient, err := dh.coreClient.GetCoreServiceClient()
4281 if err != nil || cClient == nil {
4282 return err
4283 }
4284 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4285 defer cancel()
4286 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004287 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4288 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004289 return err
4290}
4291
4292func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4293 cClient, err := dh.coreClient.GetCoreServiceClient()
4294 if err != nil || cClient == nil {
4295 return err
4296 }
4297 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4298 defer cancel()
4299 _, err = cClient.DeviceUpdate(subCtx, device)
4300 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4301 return err
4302}
4303
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004304func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004305 cClient, err := dh.coreClient.GetCoreServiceClient()
4306 if err != nil || cClient == nil {
4307 return err
4308 }
4309 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4310 defer cancel()
4311 _, err = cClient.PortCreated(subCtx, port)
4312 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4313 return err
4314}
4315
khenaidoo42dcdfd2021-10-19 17:34:12 -04004316func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004317 cClient, err := dh.coreClient.GetCoreServiceClient()
4318 if err != nil || cClient == nil {
4319 return err
4320 }
4321 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4322 defer cancel()
4323 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004324 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 -04004325 return err
4326}
4327
khenaidoo42dcdfd2021-10-19 17:34:12 -04004328func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004329 cClient, err := dh.coreClient.GetCoreServiceClient()
4330 if err != nil || cClient == nil {
4331 return err
4332 }
4333 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4334 defer cancel()
4335 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004336 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 -04004337 return err
4338}
4339
4340/*
4341Helper functions to communicate with parent adapter
4342*/
4343
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004344func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4345 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4346
4347 var request = ia.TechProfileInstanceRequestMessage{
4348 DeviceId: dh.DeviceID,
4349 TpInstancePath: aTpPath,
4350 ParentDeviceId: dh.parentID,
4351 ParentPonPort: dh.device.ParentPortNo,
4352 OnuId: dh.device.ProxyAddress.OnuId,
4353 UniId: uint32(aUniID),
4354 }
4355
4356 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004357 if err != nil || pgClient == nil {
4358 return nil, err
4359 }
4360 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4361 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004362 logger.Debugw(subCtx, "get-tech-profile-instance",
4363 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004364 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004365}
4366
Girish Gowdrae95687a2021-09-08 16:30:58 -07004367// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4368// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4369func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4370 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4371 dh.setFlowMonitoringIsRunning(uniID, true)
4372 for {
4373 select {
4374 // block on the channel to receive an incoming flow
4375 // process the flow completely before proceeding to handle the next flow
4376 case flowCb := <-dh.flowCbChan[uniID]:
4377 startTime := time.Now()
4378 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4379 respChan := make(chan error)
4380 if flowCb.addFlow {
4381 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4382 } else {
4383 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4384 }
4385 // Block on response and tunnel it back to the caller
4386 *flowCb.respChan <- <-respChan
4387 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4388 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4389 case <-dh.stopFlowMonitoringRoutine[uniID]:
4390 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4391 dh.setFlowMonitoringIsRunning(uniID, false)
4392 return
4393 }
4394 }
4395}
4396
kesavand011d5162021-11-25 19:21:06 +05304397func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4398 request.ParentDeviceId = dh.GetProxyAddressID()
4399 request.ChildDeviceId = dh.DeviceID
4400 request.ProxyAddress = dh.GetProxyAddress()
4401 request.ConnectStatus = common.ConnectStatus_REACHABLE
4402
4403 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4404 if err != nil || pgClient == nil {
4405 return err
4406 }
4407 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4408 defer cancel()
4409 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4410 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4411 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004412 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4413 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304414 }
4415 return err
4416}
4417
khenaidoo42dcdfd2021-10-19 17:34:12 -04004418func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004419 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4420 if err != nil || pgClient == nil {
4421 return err
4422 }
4423 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4424 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004425 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004426 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4427 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004428 logger.Errorw(ctx, "omci-failure",
4429 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4430 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004431 }
4432 return err
4433}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004434
Holger Hildebrandt5ba6c132022-10-06 13:53:14 +00004435func (dh *deviceHandler) CheckAvailableOnuCapabilities(ctx context.Context, pDevEntry *mib.OnuDeviceEntry, tpInst tech_profile.TechProfileInstance) error {
4436 // Check if there are additional TCONT instances necessary/available
4437 pDevEntry.MutexPersOnuConfig.Lock()
4438 if _, ok := pDevEntry.SOnuPersistentData.PersTcontMap[uint16(tpInst.UsScheduler.AllocId)]; !ok {
4439 numberOfTcontMapEntries := len(pDevEntry.SOnuPersistentData.PersTcontMap)
4440 pDevEntry.MutexPersOnuConfig.Unlock()
4441 numberOfTcontDbInsts := pDevEntry.GetOnuDB().GetNumberOfInst(me.TContClassID)
4442 logger.Debugw(ctx, "checking available TCONT instances",
4443 log.Fields{"device-id": dh.DeviceID, "numberOfTcontMapEntries": numberOfTcontMapEntries, "numberOfTcontDbInsts": numberOfTcontDbInsts})
4444 if numberOfTcontMapEntries >= numberOfTcontDbInsts {
4445 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of TCONT instances: send ONU device event!",
4446 log.Fields{"device-id": dh.device.Id})
4447 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingTcont, cmn.OnuConfigFailureMissingTcontDesc)
4448 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of TCONT instances: device-id: %s", dh.DeviceID))
4449 }
4450 } else {
4451 pDevEntry.MutexPersOnuConfig.Unlock()
4452 }
4453 // Check if there are enough PrioQueue instances available
4454 if dh.pOnuTP != nil {
4455 var numberOfUsPrioQueueDbInsts int
4456
4457 queueInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(ctx, me.PriorityQueueClassID)
4458 for _, mgmtEntityID := range queueInstKeys {
4459 if mgmtEntityID >= 0x8000 && mgmtEntityID <= 0xFFFF {
4460 numberOfUsPrioQueueDbInsts++
4461 }
4462 }
4463 // Check if there is an upstream PriorityQueue instance available for each Gem port
4464 numberOfConfiguredGemPorts := dh.pOnuTP.GetNumberOfConfiguredUsGemPorts(ctx)
4465 logger.Debugw(ctx, "checking available upstream PriorityQueue instances",
4466 log.Fields{"device-id": dh.DeviceID,
4467 "numberOfConfiguredGemPorts": numberOfConfiguredGemPorts,
4468 "tpInst.NumGemPorts": tpInst.NumGemPorts,
4469 "numberOfUsPrioQueueDbInsts": numberOfUsPrioQueueDbInsts})
4470
4471 if numberOfConfiguredGemPorts+int(tpInst.NumGemPorts) > numberOfUsPrioQueueDbInsts {
4472 logger.Errorw(ctx, "configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: send ONU device event!",
4473 log.Fields{"device-id": dh.device.Id})
4474 pDevEntry.SendOnuDeviceEvent(ctx, cmn.OnuConfigFailureMissingUsPriorityQueue, cmn.OnuConfigFailureMissingUsPriorityQueueDesc)
4475 return fmt.Errorf(fmt.Sprintf("configuration exceeds ONU capabilities - running out of upstream PrioQueue instances: device-id: %s", dh.DeviceID))
4476 }
4477 // Downstream PrioQueue instances are evaluated in accordance with ONU MIB upload data in function UniPonAniConfigFsm::prepareAndEnterConfigState().
4478 // In case of missing downstream PrioQueues the attribute "Priority queue pointer for downstream" of ME "GEM port network CTP" will be set to "0",
4479 // which then alternatively activates the queuing mechanisms of the ONU (refer to Rec. ITU-T G.988 chapter 9.2.3).
4480 } else {
4481 logger.Warnw(ctx, "onuTechProf instance not set up - check for PriorityQueue instances skipped!",
4482 log.Fields{"device-id": dh.DeviceID})
4483 }
4484 return nil
4485}
4486
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004487// GetDeviceID - TODO: add comment
4488func (dh *deviceHandler) GetDeviceID() string {
4489 return dh.DeviceID
4490}
4491
4492// GetProxyAddressID - TODO: add comment
4493func (dh *deviceHandler) GetProxyAddressID() string {
4494 return dh.device.ProxyAddress.GetDeviceId()
4495}
4496
4497// GetProxyAddressType - TODO: add comment
4498func (dh *deviceHandler) GetProxyAddressType() string {
4499 return dh.device.ProxyAddress.GetDeviceType()
4500}
4501
4502// GetProxyAddress - TODO: add comment
4503func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4504 return dh.device.ProxyAddress
4505}
4506
4507// GetEventProxy - TODO: add comment
4508func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4509 return dh.EventProxy
4510}
4511
4512// GetOmciTimeout - TODO: add comment
4513func (dh *deviceHandler) GetOmciTimeout() int {
4514 return dh.pOpenOnuAc.omciTimeout
4515}
4516
4517// GetAlarmAuditInterval - TODO: add comment
4518func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4519 return dh.pOpenOnuAc.alarmAuditInterval
4520}
4521
4522// GetDlToOnuTimeout4M - TODO: add comment
4523func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4524 return dh.pOpenOnuAc.dlToOnuTimeout4M
4525}
4526
4527// GetUniEntityMap - TODO: add comment
4528func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4529 return &dh.uniEntityMap
4530}
4531
4532// GetPonPortNumber - TODO: add comment
4533func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4534 return &dh.ponPortNumber
4535}
4536
4537// GetUniVlanConfigFsm - TODO: add comment
4538func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004539 dh.lockVlanConfig.RLock()
4540 value := dh.UniVlanConfigFsmMap[uniID]
4541 dh.lockVlanConfig.RUnlock()
4542 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004543}
4544
4545// GetOnuAlarmManager - TODO: add comment
4546func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4547 return dh.pAlarmMgr
4548}
4549
4550// GetOnuMetricsManager - TODO: add comment
4551func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4552 return dh.pOnuMetricsMgr
4553}
4554
4555// GetOnuTP - TODO: add comment
4556func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4557 return dh.pOnuTP
4558}
4559
4560// GetBackendPathPrefix - TODO: add comment
4561func (dh *deviceHandler) GetBackendPathPrefix() string {
4562 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4563}
4564
4565// GetOnuIndication - TODO: add comment
4566func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4567 return dh.pOnuIndication
4568}
4569
4570// RLockMutexDeletionInProgressFlag - TODO: add comment
4571func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4572 dh.mutexDeletionInProgressFlag.RLock()
4573}
4574
4575// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4576func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4577 dh.mutexDeletionInProgressFlag.RUnlock()
4578}
4579
4580// GetDeletionInProgress - TODO: add comment
4581func (dh *deviceHandler) GetDeletionInProgress() bool {
4582 return dh.deletionInProgress
4583}
4584
4585// GetPmConfigs - TODO: add comment
4586func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4587 return dh.pmConfigs
4588}
4589
4590// GetDeviceType - TODO: add comment
4591func (dh *deviceHandler) GetDeviceType() string {
4592 return dh.DeviceType
4593}
4594
4595// GetLogicalDeviceID - TODO: add comment
4596func (dh *deviceHandler) GetLogicalDeviceID() string {
4597 return dh.logicalDeviceID
4598}
4599
4600// GetDevice - TODO: add comment
4601func (dh *deviceHandler) GetDevice() *voltha.Device {
4602 return dh.device
4603}
4604
4605// GetMetricsEnabled - TODO: add comment
4606func (dh *deviceHandler) GetMetricsEnabled() bool {
4607 return dh.pOpenOnuAc.MetricsEnabled
4608}
4609
Holger Hildebrandtc572e622022-06-22 09:19:17 +00004610// GetExtendedOmciSupportEnabled - TODO: add comment
4611func (dh *deviceHandler) GetExtendedOmciSupportEnabled() bool {
4612 return dh.pOpenOnuAc.ExtendedOmciSupportEnabled
4613}
4614
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004615// InitPmConfigs - TODO: add comment
4616func (dh *deviceHandler) InitPmConfigs() {
4617 dh.pmConfigs = &voltha.PmConfigs{}
4618}
4619
4620// GetUniPortMask - TODO: add comment
4621func (dh *deviceHandler) GetUniPortMask() int {
4622 return dh.pOpenOnuAc.config.UniPortMask
4623}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004624
4625func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4626 tpPathFound := false
4627 for _, tpPath := range aTpPathMap {
4628 if tpPath != "" {
4629 tpPathFound = true
4630 }
4631 }
4632 return tpPathFound
4633}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004634
4635// PrepareForGarbageCollection - remove references to prepare for garbage collection
4636func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4637 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4638
4639 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4640 // first let the objects rest for some time to give all asynchronously started
4641 // cleanup routines a chance to come to an end
Holger Hildebrandt12609a12022-03-25 13:23:25 +00004642 time.Sleep(2 * time.Second)
4643
4644 if dh.pOnuOmciDevice != nil {
4645 if dh.pOnuOmciDevice.PDevOmciCC != nil {
4646 // Since we cannot rule out that one of the handlers had initiated any OMCI configurations during its
4647 // reset handling (even in future coding), request monitoring is canceled here one last time to
4648 // be sure that all corresponding go routines are terminated
4649 dh.pOnuOmciDevice.PDevOmciCC.CancelRequestMonitoring(ctx)
4650 }
4651 }
4652 time.Sleep(3 * time.Second)
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004653
4654 if dh.pOnuTP != nil {
4655 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4656 }
4657 if dh.pOnuMetricsMgr != nil {
4658 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
Girish Gowdraabcceb12022-04-13 23:35:22 -07004659 select {
4660 case <-dh.pOnuMetricsMgr.GarbageCollectionComplete:
4661 logger.Debugw(ctx, "pm fsm shut down and garbage collection complete", log.Fields{"deviceID": aDeviceID})
4662 case <-time.After(pmmgr.MaxTimeForPmFsmShutDown * time.Second):
4663 logger.Errorw(ctx, "fsm did not shut down in time", log.Fields{"deviceID": aDeviceID})
4664 }
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004665 }
4666 if dh.pAlarmMgr != nil {
4667 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4668 }
4669 if dh.pSelfTestHdlr != nil {
4670 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4671 }
4672 if dh.pLockStateFsm != nil {
4673 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4674 }
4675 if dh.pUnlockStateFsm != nil {
4676 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4677 }
4678 if dh.pOnuUpradeFsm != nil {
4679 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4680 }
4681 if dh.pOnuOmciDevice != nil {
4682 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4683 }
4684 for k, v := range dh.UniVlanConfigFsmMap {
4685 v.PrepareForGarbageCollection(ctx, aDeviceID)
4686 delete(dh.UniVlanConfigFsmMap, k)
4687 }
4688 dh.pOnuOmciDevice = nil
4689 dh.pOnuTP = nil
4690 dh.pOnuMetricsMgr = nil
4691 dh.pAlarmMgr = nil
4692 dh.pSelfTestHdlr = nil
4693 dh.pLockStateFsm = nil
4694 dh.pUnlockStateFsm = nil
4695 dh.pOnuUpradeFsm = nil
4696}