blob: 920802a328ff7492c113092b5ceecc6d1feca931 [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 {
Girish Gowdra50e56422021-06-01 16:46:04 -0700409 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800410 return err
411 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000412 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
413 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000414
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000415 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530416
Girish Gowdra50e56422021-06-01 16:46:04 -0700417 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400418 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000419 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
420 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700421 // if there has been some change for some uni TechProfilePath
422 //in order to allow concurrent calls to other dh instances we do not wait for execution here
423 //but doing so we can not indicate problems to the caller (who does what with that then?)
424 //by now we just assume straightforward successful execution
425 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
426 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530427
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 // deadline context to ensure completion of background routines waited for
429 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
430 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
431 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000433 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700434
435 var wg sync.WaitGroup
436 wg.Add(1) // for the 1 go routine to finish
437 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000438 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000440 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
441 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 -0700442 return tpErr
443 }
444 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
445 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000446 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700447 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000448 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700449 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000450 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
451 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 -0700452 return kvErr
453 }
454 return nil
455 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000456 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700457 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700458 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530459 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000460 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000461 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
462 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530463 return nil
464}
465
khenaidoo42dcdfd2021-10-19 17:34:12 -0400466func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000467 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530468
469 if dh.pOnuTP == nil {
470 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000471 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000472 log.Fields{"device-id": dh.DeviceID})
473 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530474 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000476 dh.pOnuTP.LockTpProcMutex()
477 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530478
mpagenko0f543222021-11-03 16:24:14 +0000479 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
480 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
481 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000483 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000484 }
485 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000486 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800487 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000488 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
489 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800490 return err
491 }
mpagenko0f543222021-11-03 16:24:14 +0000492 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
493 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000494 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495
Mahir Gunyel9545be22021-07-04 15:53:16 -0700496 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000498
Himani Chawla26e555c2020-08-31 12:30:20 +0530499}
500
khenaidoo42dcdfd2021-10-19 17:34:12 -0400501func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000502 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 +0000503
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000504 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000505 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000506 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
507 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000508 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530509 if dh.pOnuTP == nil {
510 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000511 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 log.Fields{"device-id": dh.DeviceID})
513 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530514 }
515
Himani Chawla26e555c2020-08-31 12:30:20 +0530516 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000517 dh.pOnuTP.LockTpProcMutex()
518 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
mpagenko0f543222021-11-03 16:24:14 +0000520 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
521 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
522 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525 }
526 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700527 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800529 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000530 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
531 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800532 return err
533 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000534 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530535
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000536 var wg sync.WaitGroup
537 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
538 dctx, cancel := context.WithDeadline(context.Background(), deadline)
539 wg.Add(1)
540 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
541 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
542 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
543 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
544 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
545 return err
546 }
547
Mahir Gunyel9545be22021-07-04 15:53:16 -0700548 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000550
Mahir Gunyel9545be22021-07-04 15:53:16 -0700551}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000552
Mahir Gunyel9545be22021-07-04 15:53:16 -0700553func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000554 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
555 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700556 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
558 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530559 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700560 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000561 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700562 resourceName = "Gem"
563 } else {
564 resourceName = "Tcont"
565 }
566
567 // deadline context to ensure completion of background routines waited for
568 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
569 dctx, cancel := context.WithDeadline(context.Background(), deadline)
570
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700572
573 var wg sync.WaitGroup
574 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700576 resource, entryID, &wg)
577 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
579 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700580 return err
581 }
582
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
584 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
585 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
586 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700587 var wg2 sync.WaitGroup
588 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
589 wg2.Add(1)
590 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000591 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 +0000592 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700593 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
595 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700596 return err
597 }
598 }
599 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000600 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700601 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530602 return nil
603}
604
mpagenkodff5dda2020-08-28 11:52:01 +0000605//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400607 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400608 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700609 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
610 var errorsList []error
611 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000612 //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 +0000613 if apOfFlowChanges.ToRemove != nil {
614 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000615 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000616 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 "device-id": dh.DeviceID})
618 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000620 continue
621 }
622 flowInPort := flow.GetInPort(flowItem)
623 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000624 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
625 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000627 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000628 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000629 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000630 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000633 continue
634 } else {
635 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000636 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000637 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
638 loUniPort = uniPort
639 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000640 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000642 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700644 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000645 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000646 }
647 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000649 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
650 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700651
652 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
653 // Step1 : Fill flowControlBlock
654 // Step2 : Push the flowControlBlock to ONU channel
655 // Step3 : Wait on response channel for response
656 // Step4 : Return error value
657 startTime := time.Now()
658 respChan := make(chan error)
659 flowCb := FlowCb{
660 ctx: ctx,
661 addFlow: false,
662 flowItem: flowItem,
663 flowMetaData: nil,
664 uniPort: loUniPort,
665 respChan: &respChan,
666 }
667 dh.flowCbChan[loUniPort.UniID] <- flowCb
668 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
669 // Wait on the channel for flow handlers return value
670 retError = <-respChan
671 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
672 if retError != nil {
673 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
674 log.Fields{"device-id": dh.DeviceID, "error": retError})
675 errorsList = append(errorsList, retError)
676 continue
677 }
678 } else {
679 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
680 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000681 }
682 }
683 }
684 }
mpagenko01e726e2020-10-23 09:45:29 +0000685 if apOfFlowChanges.ToAdd != nil {
686 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
687 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000689 "device-id": dh.DeviceID})
690 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700691 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000692 continue
693 }
694 flowInPort := flow.GetInPort(flowItem)
695 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000696 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
697 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700698 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000699 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000700 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000701 } else if flowInPort == dh.ponPortNumber {
702 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000704 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000705 continue
706 } else {
707 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000708 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000709 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
710 loUniPort = uniPort
711 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000712 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000713 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000714 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000715 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700716 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000717 continue
mpagenko01e726e2020-10-23 09:45:29 +0000718 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000719 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
720 // if not, we just throw some error here to have an indication about that, if we really need to support that
721 // then we would need to create some means to activate the internal stored flows
722 // after the device gets active automatically (and still with its dependency to the TechProfile)
723 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
724 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 if !dh.IsReadyForOmciConfig() {
726 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
727 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700728 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
729 errorsList = append(errorsList, retError)
730 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000731 }
732
mpagenko01e726e2020-10-23 09:45:29 +0000733 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000735 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
736 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700737 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
738 // Step1 : Fill flowControlBlock
739 // Step2 : Push the flowControlBlock to ONU channel
740 // Step3 : Wait on response channel for response
741 // Step4 : Return error value
742 startTime := time.Now()
743 respChan := make(chan error)
744 flowCb := FlowCb{
745 ctx: ctx,
746 addFlow: true,
747 flowItem: flowItem,
748 flowMetaData: apFlowMetaData,
749 uniPort: loUniPort,
750 respChan: &respChan,
751 }
752 dh.flowCbChan[loUniPort.UniID] <- flowCb
753 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
754 // Wait on the channel for flow handlers return value
755 retError = <-respChan
756 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
757 if retError != nil {
758 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
759 log.Fields{"device-id": dh.DeviceID, "error": retError})
760 errorsList = append(errorsList, retError)
761 continue
762 }
763 } else {
764 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
765 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000766 }
767 }
768 }
769 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700770 if len(errorsList) > 0 {
771 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
772 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
773 }
774 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000775}
776
Himani Chawla6d2ae152020-09-02 13:11:20 +0530777//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000778//following are the expected device states after this activity:
779//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
780// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
782 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300783 dh.mutexForDisableDeviceRequested.Lock()
784 dh.disableDeviceRequested = true
785 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000786 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000787 //note that disableDevice sequences in some 'ONU active' state may yield also
788 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000789 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000791 //disable-device shall be just a UNi/ONU-G related admin state setting
792 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000793
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000794 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000795 // disable UNI ports/ONU
796 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
797 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000798 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000799 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000802 }
803 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000804 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000805 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000806 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400807 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000808 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000809 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400810 OperStatus: voltha.OperStatus_UNKNOWN,
811 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000812 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000813 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000814 }
mpagenko01e726e2020-10-23 09:45:29 +0000815 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000816
817 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000818 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000819 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300820 }
821}
822
Himani Chawla6d2ae152020-09-02 13:11:20 +0530823//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
825 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000826
mpagenkoaa3afe92021-05-21 16:20:58 +0000827 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000828 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
829 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
830 // for real ONU's that should have nearly no influence
831 // Note that for real ONU's there is anyway a problematic situation with following sequence:
832 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
833 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
834 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000835 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000836
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000837 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300839 dh.mutexForDisableDeviceRequested.Lock()
840 dh.disableDeviceRequested = false
841 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000842 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000843 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000844 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000845 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000847 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300848}
849
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000852
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000853 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000854 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000855 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000856 return
857 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000859 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000861 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000862 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000863 }
mpagenko101ac942021-11-16 15:01:29 +0000864 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000865 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000866 }
Himani Chawla4d908332020-08-31 12:30:20 +0530867 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 pDevEntry.MutexPersOnuConfig.RLock()
869 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
870 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
871 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
872 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
873 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000875}
876
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000877func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000879
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000880 continueWithFlowConfig := false
881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000882 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000884 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000885 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
886 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 dh.pOnuTP.LockTpProcMutex()
889 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000891 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000892 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
894 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000896 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000897 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
898 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000899 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000900 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700901 techProfsFound := false
902 techProfInstLoadFailed := false
903outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000904 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000905 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000907 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000909 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000910 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000911 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
913 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000914 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000915 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000916 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700917 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000918 var iaTechTpInst ia.TechProfileDownloadMessage
919 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800920 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000921 pDevEntry.MutexReconciledTpInstances.RLock()
922 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
923 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000924 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000925 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700926 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000927 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700928 break outerLoop
929 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000930 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000931 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 var tpInst tech_profile.TechProfileInstance
933 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400934 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700935 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000936 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000937 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700938 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000939 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000940 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700941 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
942 break outerLoop
943 }
944
Girish Gowdra041dcb32020-11-16 16:54:30 -0800945 // deadline context to ensure completion of background routines waited for
946 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
947 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000949
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800951 var wg sync.WaitGroup
952 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000954 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
956 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700957 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
958 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800959 }
mpagenko2dc896e2021-08-02 12:03:59 +0000960 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000961 if len(uniData.PersFlowParams) != 0 {
962 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000963 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000965 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000966 } // for all UNI entries from SOnuPersistentData
967 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
968 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000969 }
mpagenko2dc896e2021-08-02 12:03:59 +0000970
971 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
972 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000973
974 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000975}
976
977func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
978 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
979 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000981 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000982 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000983 return
984 }
mpagenko2dc896e2021-08-02 12:03:59 +0000985 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000986 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000987 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700988 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000990 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000991 }
mpagenko2dc896e2021-08-02 12:03:59 +0000992 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000993 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000995 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000996 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997}
998
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1000 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001003 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001004 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001005 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001006 return
1007 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001009 pDevEntry.MutexPersOnuConfig.RLock()
1010 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1011 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001013 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001014 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001015 return
1016 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001017 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001018 var uniVlanConfigEntries []uint8
1019 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001021 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001022 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1023 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001025 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001026 continue
1027 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001028 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001029 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001030 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001031 // It doesn't make sense to configure any flows if no TPs are available
1032 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001033 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001034 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1035 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001036 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001037 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001038
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001040 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001041 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001042 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1044 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001045 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001046 return
1047 }
mpagenko101ac942021-11-16 15:01:29 +00001048 //needed to split up function due to sca complexity
1049 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1050
mpagenko2dc896e2021-08-02 12:03:59 +00001051 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001052 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001053 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1054 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001055 // this can't be used as global finished reconciling flag because
1056 // assumes is getting called before the state machines for the last flow is completed,
1057 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001058 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1059 } // for all UNI entries from SOnuPersistentData
1060 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001061
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001062 if !flowsFound {
1063 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001064 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001065 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001066 return
1067 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001068 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1069 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1070 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1071 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1072 log.Fields{"device-id": dh.DeviceID})
1073 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1074 if pDevEntry != nil {
1075 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001076 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001077 } else {
1078 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1079 log.Fields{"device-id": dh.DeviceID})
1080 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1081 if pDevEntry != nil {
1082 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1083 }
1084 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001085 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001086 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001087}
1088
mpagenko101ac942021-11-16 15:01:29 +00001089func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1090 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1091 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1092 flowsProcessed := 0
1093 lastFlowToReconcile := false
1094 loUniID := apUniPort.UniID
1095 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001096 if !(*apFlowsFound) {
1097 *apFlowsFound = true
1098 syncChannel := make(chan struct{})
1099 // start go routine with select() on reconciling vlan config channel before
1100 // starting vlan config reconciling process to prevent loss of any signal
1101 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1102 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1103 //block until the wait routine is really blocked on channel input
1104 // in order to prevent to early ready signal from VlanConfig processing
1105 <-syncChannel
1106 }
1107 if flowsProcessed == len(aPersFlowParam)-1 {
1108 var uniAdded bool
1109 lastFlowToReconcile = true
1110 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1111 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001112 }
1113 }
mpagenko101ac942021-11-16 15:01:29 +00001114 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1115 "device-id": dh.DeviceID, "uni-id": loUniID,
1116 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1117 dh.lockVlanConfig.Lock()
1118 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1119 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1120 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1121 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1122 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1123 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1124 }
1125 } else {
1126 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1127 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1128 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1129 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1130 }
1131 }
1132 dh.lockVlanConfig.Unlock()
1133 flowsProcessed++
1134 } //for all flows of this UNI
1135}
1136
1137//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1138// and decrements the according handler wait group waiting for these indications
1139func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1140 waitGroup *cmn.WaitGroupWithTimeOut) {
1141 var reconciledUniVlanConfigEntries []uint8
1142 var appended bool
1143 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1144 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1145 "device-id": dh.DeviceID, "expiry": expiry})
1146 // indicate blocking on channel now to the caller
1147 aSyncChannel <- struct{}{}
1148 for {
1149 select {
1150 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1151 switch uniIndication {
1152 // no activity requested (should normally not be received) - just continue waiting
1153 case cWaitReconcileFlowNoActivity:
1154 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1155 case cWaitReconcileFlowAbortOnError:
1156 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1157 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1158 return
1159 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1160 case cWaitReconcileFlowAbortOnSuccess:
1161 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1162 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1163 return
1164 // this should be a valid UNI vlan config done indication
1165 default:
1166 if uniIndication < platform.MaxUnisPerOnu {
1167 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1168 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1169 if reconciledUniVlanConfigEntries, appended =
1170 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1171 waitGroup.Done()
1172 }
1173 } else {
1174 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1175 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1176 }
1177 } //switch uniIndication
1178
1179 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1180 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1181 log.Fields{"device-id": dh.DeviceID})
1182 return
1183 }
1184 }
1185}
1186
1187func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1188 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1189}
1190
1191func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1192 for _, ele := range slice {
1193 if ele == val {
1194 return slice, false
1195 }
1196 }
1197 return append(slice, val), true
1198}
1199
1200// sendChReconcileFinished - sends true or false on reconcileFinish channel
1201func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1202 if dh != nil { //if the object still exists (might have been already deleted in background)
1203 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1204 select {
1205 case dh.chReconcilingFinished <- success:
1206 default:
1207 }
1208 }
1209}
1210
1211// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1212func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1213 if dh != nil { //if the object still exists (might have been already deleted in background)
1214 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1215 select {
1216 case dh.chUniVlanConfigReconcilingDone <- value:
1217 default:
1218 }
1219 }
1220}
1221
dbainbri4d3a0dc2020-12-02 00:33:42 +00001222func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001223 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001224
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001225 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001226 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001227 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001229 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001230 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001231
1232 // deadline context to ensure completion of background routines waited for
1233 //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 +05301234 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001236
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001238
1239 var wg sync.WaitGroup
1240 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001243
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001244 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001246}
1247
mpagenko15ff4a52021-03-02 10:09:20 +00001248//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1249// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001251//was and is called in background - error return does not make sense
1252func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001253 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001254 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001256 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001257 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001258 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301259 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001260 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001261 return
Himani Chawla4d908332020-08-31 12:30:20 +05301262 }
mpagenko01e726e2020-10-23 09:45:29 +00001263
1264 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001266
mpagenko44bd8362021-11-15 11:40:05 +00001267 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001269 // 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 -04001270 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001272 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001273 OperStatus: voltha.OperStatus_DISCOVERED,
1274 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001275 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001276 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001277 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001278 }
mpagenkoe4782082021-11-25 12:04:26 +00001279 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001280 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001281 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001283 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1284 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1285 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1286 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001287}
1288
mpagenkoc8bba412021-01-15 15:38:44 +00001289//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001290// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001291func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001293 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001295
1296 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001298 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1300 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001301 }
1302
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001304 var inactiveImageID uint16
1305 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1306 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001307 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1308 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001309 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001311 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001312 if err == nil {
1313 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1314 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001315 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001316 }
1317 } else {
1318 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001320 }
mpagenko15ff4a52021-03-02 10:09:20 +00001321 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001322 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001324 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1325 dh.upgradeCanceled = true
1326 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1327 }
mpagenko38662d02021-08-11 09:45:19 +00001328 //no effort spent anymore for the old API to automatically cancel and restart the download
1329 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001330 }
mpagenko15ff4a52021-03-02 10:09:20 +00001331 } else {
1332 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001334 }
1335 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1337 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001338 }
1339 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001340}
1341
mpagenkoc26d4c02021-05-06 14:27:57 +00001342//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1343// after the OnuImage has been downloaded to the adapter, called in background
1344func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001345 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001346
1347 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001349 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001351 return
1352 }
1353
1354 var inactiveImageID uint16
1355 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1356 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001358
mpagenko59862f02021-10-11 08:53:18 +00001359 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001361 // but must be still locked at calling createOnuUpgradeFsm
1362 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1363 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1364 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001365 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1366 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001367 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001368 //flush the remove upgradeFsmChan channel
1369 select {
1370 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001371 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001372 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001373 }
mpagenko59862f02021-10-11 08:53:18 +00001374 dh.lockUpgradeFsm.Unlock()
1375 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1376 dh.upgradeCanceled = true
1377 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1378 }
mpagenko38662d02021-08-11 09:45:19 +00001379 select {
1380 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001382 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1383 return
1384 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001386 }
mpagenko59862f02021-10-11 08:53:18 +00001387 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001388 }
mpagenko38662d02021-08-11 09:45:19 +00001389
1390 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001391 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001392 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001393 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001394 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001395 if err == nil {
1396 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1397 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1398 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001400 return
1401 }
mpagenko38662d02021-08-11 09:45:19 +00001402 } else {
1403 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001405 }
1406 return
1407 }
1408 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001410}
1411
1412//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001413func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1414 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001415 var err error
1416 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1417 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1418 // 2.) activation of the inactive image
1419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001421 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1423 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 }
1425 dh.lockUpgradeFsm.RLock()
1426 if dh.pOnuUpradeFsm != nil {
1427 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001428 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001429 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1431 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432 }
mpagenko59862f02021-10-11 08:53:18 +00001433 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1434 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1435 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1436 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001437 // use the OnuVendor identification from this device for the internal unique name
1438 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001439 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001441 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001442 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001443 "device-id": dh.DeviceID, "error": err})
1444 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001445 }
mpagenko183647c2021-06-08 15:25:04 +00001446 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001447 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001448 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001449 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001450 } //else
1451 dh.lockUpgradeFsm.RUnlock()
1452
1453 // 2.) check if requested image-version equals the inactive one and start its activation
1454 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1455 var inactiveImageID uint16
1456 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1457 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001458 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1459 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001460 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001461 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001463 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001464 if err == nil {
1465 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1466 inactiveImageID, aCommitRequest); err != nil {
1467 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 "device-id": dh.DeviceID, "error": err})
1469 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001470 }
1471 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001472 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001473 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001474 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001475 } //else
1476 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 "device-id": dh.DeviceID, "error": err})
1478 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001479}
1480
1481//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001482func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1483 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001484 var err error
1485 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1486 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1487 // 2.) commitment of the active image
1488
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001490 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001491 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1492 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 }
1494 dh.lockUpgradeFsm.RLock()
1495 if dh.pOnuUpradeFsm != nil {
1496 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001497 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001498 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001499 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1500 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 }
mpagenko59862f02021-10-11 08:53:18 +00001502 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1503 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1504 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1505 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001506 // use the OnuVendor identification from this device for the internal unique name
1507 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001508 // 1.) check a started upgrade process and relay the commitment request to it
1509 // the running upgrade may be based either on the imageIdentifier (started from download)
1510 // or on the imageVersion (started from pure activation)
1511 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1512 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001513 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001514 "device-id": dh.DeviceID, "error": err})
1515 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 }
mpagenko183647c2021-06-08 15:25:04 +00001517 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001519 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001520 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001521 } //else
1522 dh.lockUpgradeFsm.RUnlock()
1523
mpagenko183647c2021-06-08 15:25:04 +00001524 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001525 var activeImageID uint16
1526 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1527 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1529 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001530 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001531 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001533 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001534 if err == nil {
1535 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1536 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 "device-id": dh.DeviceID, "error": err})
1538 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001539 }
1540 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001541 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001542 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001543 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001544 } //else
1545 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001546 "device-id": dh.DeviceID, "error": err})
1547 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001548}
1549
mpagenkoaa3afe92021-05-21 16:20:58 +00001550func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001551 aVersion string) *voltha.ImageState {
1552 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001553 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001554 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001555 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001556 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1557 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1558 if aVersion == dh.pLastUpgradeImageState.Version {
1559 pImageState = dh.pLastUpgradeImageState
1560 } else { //state request for an image version different from last processed image version
1561 pImageState = &voltha.ImageState{
1562 Version: aVersion,
1563 //we cannot state something concerning this version
1564 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1565 Reason: voltha.ImageState_NO_ERROR,
1566 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1567 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001568 }
1569 }
mpagenko38662d02021-08-11 09:45:19 +00001570 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001571}
1572
1573func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1574 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001576 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001577 dh.lockUpgradeFsm.RLock()
1578 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001579 dh.lockUpgradeFsm.RUnlock()
1580 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001581 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001582 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1583 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1584 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1585 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1586 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1587 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001588 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1589 dh.upgradeCanceled = true
1590 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1591 }
mpagenko45586762021-10-01 08:30:22 +00001592 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001593 } else {
mpagenko45586762021-10-01 08:30:22 +00001594 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001595 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1596 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1597 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1598 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1599 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1600 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001601 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1602 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001603 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1604 //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 +00001605 }
1606}
1607
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001608func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1609
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001610 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001613 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001614 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1615 pDevEntry.MutexOnuImageStatus.Lock()
1616 pDevEntry.POnuImageStatus = onuImageStatus
1617 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001618
1619 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001621 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1622 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1624 pDevEntry.MutexOnuImageStatus.Lock()
1625 pDevEntry.POnuImageStatus = nil
1626 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001627 return images, err
1628}
1629
Himani Chawla6d2ae152020-09-02 13:11:20 +05301630// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001631// #####################################################################################
1632
1633// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301634// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001637 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1638 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001639}
1640
1641// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001644 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001645 var err error
1646
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 // populate what we know. rest comes later after mib sync
1648 dh.device.Root = false
1649 dh.device.Vendor = "OpenONU"
1650 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001652 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001653
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 if !dh.IsReconciling() {
1657 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001658 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1659 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1660 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301661 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001662 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001664 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001665 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666
Himani Chawla4d908332020-08-31 12:30:20 +05301667 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001668 dh.ponPortNumber = dh.device.ParentPortNo
1669
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001670 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1671 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1672 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001674 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301675 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676
1677 /*
1678 self._pon = PonPort.create(self, self._pon_port_number)
1679 self._pon.add_peer(self.parent_id, self._pon_port_number)
1680 self.logger.debug('adding-pon-port-to-agent',
1681 type=self._pon.get_port().type,
1682 admin_state=self._pon.get_port().admin_state,
1683 oper_status=self._pon.get_port().oper_status,
1684 )
1685 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 if !dh.IsReconciling() {
1687 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001688 var ponPortNo uint32 = 1
1689 if dh.ponPortNumber != 0 {
1690 ponPortNo = dh.ponPortNumber
1691 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001692
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001693 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001695 PortNo: ponPortNo,
1696 Label: fmt.Sprintf("pon-%d", ponPortNo),
1697 Type: voltha.Port_PON_ONU,
1698 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301699 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001700 PortNo: ponPortNo}}, // Peer port is parent's port number
1701 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001702 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001703 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001704 e.Cancel(err)
1705 return
1706 }
1707 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001710 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711}
1712
1713// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001715
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001716 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001717 var err error
1718 /*
1719 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1720 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1721 return nil
1722 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001724 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001725 e.Cancel(err)
1726 return
1727 }
1728
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001729 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001731 // reconcilement will be continued after mib download is done
1732 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001733
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001734 /*
1735 ############################################################################
1736 # Setup Alarm handler
1737 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1738 device.serial_number)
1739 ############################################################################
1740 # Setup PM configuration for this device
1741 # Pass in ONU specific options
1742 kwargs = {
1743 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1744 'heartbeat': self.heartbeat,
1745 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1746 }
1747 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1748 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1749 self.logical_device_id, device.serial_number,
1750 grouped=True, freq_override=False, **kwargs)
1751 pm_config = self._pm_metrics.make_proto()
1752 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1753 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1754 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1755
1756 # Note, ONU ID and UNI intf set in add_uni_port method
1757 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1758 ani_ports=[self._pon])
1759
1760 # Code to Run OMCI Test Action
1761 kwargs_omci_test_action = {
1762 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1763 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1764 }
1765 serial_number = device.serial_number
1766 self._test_request = OmciTestRequest(self.core_proxy,
1767 self.omci_agent, self.device_id,
1768 AniG, serial_number,
1769 self.logical_device_id,
1770 exclusive=False,
1771 **kwargs_omci_test_action)
1772
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001773 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001774 else:
1775 self.logger.info('onu-already-activated')
1776 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001777
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001778 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001779}
1780
1781// doStateConnected get the device info and update to voltha core
1782// for comparison of the original method (not that easy to uncomment): compare here:
1783// voltha-openolt-adapter/adaptercore/device_handler.go
1784// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001786
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001787 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301788 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001789 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001790 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791}
1792
1793// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794func (dh *deviceHandler) doStateUp(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, "doStateUp-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, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800
1801 /*
1802 // Synchronous call to update device state - this method is run in its own go routine
1803 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1804 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001805 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 +00001806 return err
1807 }
1808 return nil
1809 */
1810}
1811
1812// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001815 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001816 var err error
1817
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001818 device := dh.device
1819 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001821 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001822 e.Cancel(err)
1823 return
1824 }
1825
1826 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001828 /*
1829 // Update the all ports state on that device to disable
1830 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001831 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001832 return er
1833 }
1834
1835 //Update the device oper state and connection status
1836 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1837 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1838 dh.device = cloned
1839
1840 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001841 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001842 return er
1843 }
1844
1845 //get the child device for the parent device
1846 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1847 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001848 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001849 return err
1850 }
1851 for _, onuDevice := range onuDevices.Items {
1852
1853 // Update onu state as down in onu adapter
1854 onuInd := oop.OnuIndication{}
1855 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001856 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001857 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1858 if er != nil {
1859 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001860 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001861 //Do not return here and continue to process other ONUs
1862 }
1863 }
1864 // * Discovered ONUs entries need to be cleared , since after OLT
1865 // is up, it starts sending discovery indications again* /
1866 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001867 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001868 return nil
1869 */
Himani Chawla4d908332020-08-31 12:30:20 +05301870 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001871 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001872 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001873}
1874
Himani Chawla6d2ae152020-09-02 13:11:20 +05301875// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001876// #################################################################################
1877
1878// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301879// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001881//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1882func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001883 dh.lockDevice.RLock()
1884 pOnuDeviceEntry := dh.pOnuOmciDevice
1885 if aWait && pOnuDeviceEntry == nil {
1886 //keep the read sema short to allow for subsequent write
1887 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001888 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001889 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1890 // so it might be needed to wait here for that event with some timeout
1891 select {
1892 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001893 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001894 return nil
1895 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001896 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001897 // if written now, we can return the written value without sema
1898 return dh.pOnuOmciDevice
1899 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001900 }
mpagenko3af1f032020-06-10 08:53:41 +00001901 dh.lockDevice.RUnlock()
1902 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001903}
1904
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001905//setDeviceHandlerEntries sets the ONU device entry within the handler
1906func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1907 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001908 dh.lockDevice.Lock()
1909 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001910 dh.pOnuOmciDevice = apDeviceEntry
1911 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001912 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301913 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001914 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001915}
1916
Himani Chawla6d2ae152020-09-02 13:11:20 +05301917//addOnuDeviceEntry creates a new ONU device or returns the existing
1918func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001919 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001920
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001921 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922 if deviceEntry == nil {
1923 /* costum_me_map in python code seems always to be None,
1924 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1925 /* also no 'clock' argument - usage open ...*/
1926 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1928 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1929 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1930 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1931 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001932 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001933 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001934 // fire deviceEntry ready event to spread to possibly waiting processing
1935 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001936 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001937 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001939 }
1940 // might be updated with some error handling !!!
1941 return nil
1942}
1943
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001945 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001946 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1947
1948 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001949
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001951 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1953 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001954 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001955 if !dh.IsReconciling() {
1956 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001958 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001959 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001962
khenaidoo42dcdfd2021-10-19 17:34:12 -04001963 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001965 OperStatus: voltha.OperStatus_ACTIVATING,
1966 ConnStatus: voltha.ConnectStatus_REACHABLE,
1967 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001968 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001970 }
1971 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001973 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 pDevEntry.MutexPersOnuConfig.RLock()
1976 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1977 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 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 +00001979 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001980 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001981 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001983 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001984 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001985 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1986 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1987 // 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 +00001988 // 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 +00001989 // so let's just try to keep it simple ...
1990 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001992 if err != nil || device == nil {
1993 //TODO: needs to handle error scenarios
1994 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1995 return errors.New("Voltha Device not found")
1996 }
1997 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001998
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001999 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002000 return err
mpagenko3af1f032020-06-10 08:53:41 +00002001 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002002 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002003
2004 /* this might be a good time for Omci Verify message? */
2005 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002006 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002007 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002008 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002009 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010
2011 /* give the handler some time here to wait for the OMCi verification result
2012 after Timeout start and try MibUpload FSM anyway
2013 (to prevent stopping on just not supported OMCI verification from ONU) */
2014 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002015 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002016 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002017 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002018 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002019 }
2020
2021 /* In py code it looks earlier (on activate ..)
2022 # Code to Run OMCI Test Action
2023 kwargs_omci_test_action = {
2024 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2025 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2026 }
2027 serial_number = device.serial_number
2028 self._test_request = OmciTestRequest(self.core_proxy,
2029 self.omci_agent, self.device_id,
2030 AniG, serial_number,
2031 self.logical_device_id,
2032 exclusive=False,
2033 **kwargs_omci_test_action)
2034 ...
2035 # Start test requests after a brief pause
2036 if not self._test_request_started:
2037 self._test_request_started = True
2038 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2039 reactor.callLater(tststart, self._test_request.start_collector)
2040
2041 */
2042 /* which is then: in omci_test_request.py : */
2043 /*
2044 def start_collector(self, callback=None):
2045 """
2046 Start the collection loop for an adapter if the frequency > 0
2047
2048 :param callback: (callable) Function to call to collect PM data
2049 """
2050 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2051 if callback is None:
2052 callback = self.perform_test_omci
2053
2054 if self.lc is None:
2055 self.lc = LoopingCall(callback)
2056
2057 if self.default_freq > 0:
2058 self.lc.start(interval=self.default_freq / 10)
2059
2060 def perform_test_omci(self):
2061 """
2062 Perform the initial test request
2063 """
2064 ani_g_entities = self._device.configuration.ani_g_entities
2065 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2066 is not None else None
2067 self._entity_id = ani_g_entities_ids[0]
2068 self.logger.info('perform-test', entity_class=self._entity_class,
2069 entity_id=self._entity_id)
2070 try:
2071 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2072 result = yield self._device.omci_cc.send(frame)
2073 if not result.fields['omci_message'].fields['success_code']:
2074 self.logger.info('Self-Test Submitted Successfully',
2075 code=result.fields[
2076 'omci_message'].fields['success_code'])
2077 else:
2078 raise TestFailure('Test Failure: {}'.format(
2079 result.fields['omci_message'].fields['success_code']))
2080 except TimeoutError as e:
2081 self.deferred.errback(failure.Failure(e))
2082
2083 except Exception as e:
2084 self.logger.exception('perform-test-Error', e=e,
2085 class_id=self._entity_class,
2086 entity_id=self._entity_id)
2087 self.deferred.errback(failure.Failure(e))
2088
2089 */
2090
2091 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002092 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002093
mpagenko1cc3cb42020-07-27 15:24:38 +00002094 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2095 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2096 * 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 +05302097 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002098 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002099 //call MibUploadFSM - transition up to state UlStInSync
2100 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002101 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002102 if pMibUlFsm.Is(mib.UlStDisabled) {
2103 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2104 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2105 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302106 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002107 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302108 //Determine ONU status and start/re-start MIB Synchronization tasks
2109 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002110 if pDevEntry.IsNewOnu() {
2111 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2112 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2113 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002114 }
Himani Chawla4d908332020-08-31 12:30:20 +05302115 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002116 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2117 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2118 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302119 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002120 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002121 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002122 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002124 "device-id": dh.DeviceID})
2125 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002126 }
2127 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002128 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2129 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002130 }
2131 return nil
2132}
2133
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002135 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002136 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002137 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2138 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002139
mpagenko900ee4b2020-10-12 11:56:34 +00002140 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2141 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2142 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002143 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002145 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002146 // abort: system behavior is just unstable ...
2147 return err
2148 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002149 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 _ = 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 +00002151
2152 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002153 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002154 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002155 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002156 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2157 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002158 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002160
2161 //TODO!!! remove existing traffic profiles
2162 /* from py code, if TP's exist, remove them - not yet implemented
2163 self._tp = dict()
2164 # Let TP download happen again
2165 for uni_id in self._tp_service_specific_task:
2166 self._tp_service_specific_task[uni_id].clear()
2167 for uni_id in self._tech_profile_download_done:
2168 self._tech_profile_download_done[uni_id].clear()
2169 */
2170
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002171 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002172
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002174
mpagenkoe4782082021-11-25 12:04:26 +00002175 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002176 // abort: system behavior is just unstable ...
2177 return err
2178 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002180 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002181 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002183 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2184 OperStatus: voltha.OperStatus_DISCOVERED,
2185 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002186 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002188 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002189 // abort: system behavior is just unstable ...
2190 return err
2191 }
2192 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002193 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002194 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002195 return nil
2196}
2197
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002198func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002199 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2200 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2201 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2202 // and using the stop/reset event should never harm
2203
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002204 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002205 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2207 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002208 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002209 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002210 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002211 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 pDevEntry.MutexOnuImageStatus.RLock()
2213 if pDevEntry.POnuImageStatus != nil {
2214 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002217
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002218 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002219 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002220 }
2221 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002222 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002223 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002224 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002225 }
mpagenko101ac942021-11-16 15:01:29 +00002226 //stop any deviceHandler reconcile processing (if running)
2227 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002228 //port lock/unlock FSM's may be active
2229 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002230 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002231 }
2232 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002233 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002234 }
2235 //techProfile related PonAniConfigFsm FSM may be active
2236 if dh.pOnuTP != nil {
2237 // should always be the case here
2238 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002239 if dh.pOnuTP.PAniConfigFsm != nil {
2240 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2241 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002242 }
mpagenko900ee4b2020-10-12 11:56:34 +00002243 }
2244 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002245 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002246 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002247 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002248 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002249 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002250 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002251 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002252 } else {
2253 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002254 }
2255 }
2256 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002257 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002258 // Stop collector routine
2259 dh.stopCollector <- true
2260 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002261 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302262 dh.stopAlarmManager <- true
2263 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002264 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002265 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002266 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302267
Girish Gowdrae95687a2021-09-08 16:30:58 -07002268 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2269
mpagenko80622a52021-02-09 16:53:23 +00002270 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002272 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002273 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002274 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002275 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002276 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002277 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2278 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2279 // (even though it may also run into direct cancellation, a bit hard to verify here)
2280 // so don't set 'dh.upgradeCanceled = true' here!
2281 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2282 }
mpagenko38662d02021-08-11 09:45:19 +00002283 }
mpagenko80622a52021-02-09 16:53:23 +00002284
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002285 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002286 return nil
2287}
2288
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2290 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 +05302291
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002292 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002293 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002294 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002295 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002296 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002297 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002298 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002299
mpagenkoa40e99a2020-11-17 13:50:39 +00002300 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2301 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2302 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2303 * disable/enable toggling here to allow traffic
2304 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2305 * like the py comment says:
2306 * # start by locking all the unis till mib sync and initial mib is downloaded
2307 * # this way we can capture the port down/up events when we are ready
2308 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302309
mpagenkoa40e99a2020-11-17 13:50:39 +00002310 // Init Uni Ports to Admin locked state
2311 // *** should generate UniLockStateDone event *****
2312 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002313 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002314 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002315 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002317 }
2318}
2319
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002320func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2321 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302322 /* Mib download procedure -
2323 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2324 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002326 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002328 return
2329 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302331 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002332 if pMibDlFsm.Is(mib.DlStDisabled) {
2333 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2334 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 +05302335 // maybe try a FSM reset and then again ... - TODO!!!
2336 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002337 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302338 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002339 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2340 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302341 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002342 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302343 //Begin MIB data download (running autonomously)
2344 }
2345 }
2346 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002347 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002348 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302349 // maybe try a FSM reset and then again ... - TODO!!!
2350 }
2351 /***** Mib download started */
2352 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002353 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302354 }
2355}
2356
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2358 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302359 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002360 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002362 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002363 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2364 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2365 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2366 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002367 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002369 ConnStatus: voltha.ConnectStatus_REACHABLE,
2370 OperStatus: voltha.OperStatus_ACTIVE,
2371 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302372 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002373 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302374 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302376 }
2377 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002379 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302380 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002381 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002382
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002384 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002386 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002387 if !dh.GetAlarmManagerIsRunning(ctx) {
2388 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002389 }
2390
Girish Gowdrae95687a2021-09-08 16:30:58 -07002391 // Start flow handler routines per UNI
2392 for _, uniPort := range dh.uniEntityMap {
2393 // only if this port was enabled for use by the operator at startup
2394 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2395 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2396 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2397 }
2398 }
2399 }
2400
Girish Gowdrae0140f02021-02-02 16:55:09 -08002401 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002402 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002403 // There is no way we should be landing here, but if we do then
2404 // there is nothing much we can do about this other than log error
2405 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2406 }
2407
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002409
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002410 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002411 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002413 return
2414 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 pDevEntry.MutexPersOnuConfig.RLock()
2416 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2417 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002418 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002420 dh.mutexForDisableDeviceRequested.Lock()
2421 dh.disableDeviceRequested = true
2422 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002423 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002424 // reconcilement will be continued after ani config is done
2425 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002426 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002427 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002428 dh.mutexForDisableDeviceRequested.RLock()
2429 if !dh.disableDeviceRequested {
2430 if dh.pUnlockStateFsm == nil {
2431 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2432 } else { //UnlockStateFSM already init
2433 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2434 dh.runUniLockFsm(ctx, false)
2435 }
2436 dh.mutexForDisableDeviceRequested.RUnlock()
2437 } else {
2438 dh.mutexForDisableDeviceRequested.RUnlock()
2439 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002440 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302441 }
2442}
2443
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002444func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2445 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302446
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 if !dh.IsReconciling() {
2448 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002449 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002450 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2451 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002452 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002454 return
2455 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002456 pDevEntry.MutexPersOnuConfig.Lock()
2457 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2458 pDevEntry.MutexPersOnuConfig.Unlock()
2459 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002462 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302463 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002464 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 +00002465 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002466 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002467 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302468 }
2469}
2470
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002471func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002472 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002474
mpagenko44bd8362021-11-15 11:40:05 +00002475 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002476 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002478 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002479 OperStatus: voltha.OperStatus_UNKNOWN,
2480 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002481 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002483 }
2484
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002486 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002487 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002488
2489 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002490 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002491
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002492 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002493 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002494 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002495 return
2496 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002497 pDevEntry.MutexPersOnuConfig.Lock()
2498 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2499 pDevEntry.MutexPersOnuConfig.Unlock()
2500 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002503 }
mpagenko900ee4b2020-10-12 11:56:34 +00002504}
2505
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002507 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002509 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002511 ConnStatus: voltha.ConnectStatus_REACHABLE,
2512 OperStatus: voltha.OperStatus_ACTIVE,
2513 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002514 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002515 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002516 }
2517
dbainbri4d3a0dc2020-12-02 00:33:42 +00002518 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002520 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002521 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002522
2523 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002525
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002526 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002527 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002528 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002529 return
2530 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 pDevEntry.MutexPersOnuConfig.Lock()
2532 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2533 pDevEntry.MutexPersOnuConfig.Unlock()
2534 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002535 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002537 }
mpagenko900ee4b2020-10-12 11:56:34 +00002538}
2539
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002540func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2541 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2542 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002543 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002544 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002545 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002546 OperStatus: voltha.OperStatus_FAILED,
2547 }); err != nil {
2548 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2549 }
2550}
2551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2553 if devEvent == cmn.OmciAniConfigDone {
2554 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002555 // attention: the device reason update is done based on ONU-UNI-Port related activity
2556 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002557 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002558 // 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 +00002559 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302560 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002562 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2563 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2564 dh.mutexReconcilingFirstPassFlag.Lock()
2565 if dh.reconcilingFirstPass {
2566 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2567 dh.reconcilingFirstPass = false
2568 go dh.ReconcileDeviceFlowConfig(ctx)
2569 }
2570 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002571 }
2572 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002573 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002574 // attention: the device reason update is done based on ONU-UNI-Port related activity
2575 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002576 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002577 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2578 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002579 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002580 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302581}
2582
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002583func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002584 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002585 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302586 // attention: the device reason update is done based on ONU-UNI-Port related activity
2587 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302588
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2590 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002591 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002592 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002593 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002594 }
2595 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002597 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002598 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002599 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302600 }
mpagenkof1fc3862021-02-16 10:09:52 +00002601
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002602 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002603 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002605 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002606 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002607 }
2608 } else {
2609 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002611 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302612}
2613
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2615func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302616 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002618 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002620 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002622 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002624 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002625 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002626 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002628 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002630 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002631 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002634 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002635 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002636 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002637 case cmn.UniEnableStateFailed:
2638 {
2639 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2640 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002641 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002642 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002644 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002645 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002646 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002647 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002648 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002649 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002650 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002652 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002653 default:
2654 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002655 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002656 }
2657 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002658}
2659
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002660func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002661 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002662 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302663 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002664 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002665 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002666 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302667 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002669 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002670 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 +00002671 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002672 //store UniPort with the System-PortNumber key
2673 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002674 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002675 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002676 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002677 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002678 } //error logging already within UniPort method
2679 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002681 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002682 }
2683 }
2684}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002685
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2687 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002688 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002690 return
2691 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002692 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002693 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002694 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2695 for _, mgmtEntityID := range pptpInstKeys {
2696 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002697 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002698 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2699 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002700 }
2701 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002702 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002703 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002705 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2706 for _, mgmtEntityID := range veipInstKeys {
2707 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002709 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2710 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002711 }
2712 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002714 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002716 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2717 for _, mgmtEntityID := range potsInstKeys {
2718 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002719 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002720 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2721 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002722 }
2723 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002724 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002725 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002726 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002728 return
2729 }
2730
mpagenko2c3f6c52021-11-23 11:22:10 +00002731 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2732 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2733 // 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 -07002734 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2735 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2736 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002737 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2738 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002739 for i := 0; i < int(uniCnt); i++ {
2740 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2741 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002742 }
2743}
2744
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2746func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002747 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302748 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002749 // with following remark:
2750 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2751 // # load on the core
2752
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002753 // 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 +00002754
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002755 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002756 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2758 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2759 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2760 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002761 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002762 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002763 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002765 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 PortNo: port.PortNo,
2767 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002768 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002769 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 -04002770 }
2771 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002772 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002773 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002774 }
mpagenko3af1f032020-06-10 08:53:41 +00002775 }
2776 }
2777}
2778
2779// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2781 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002782 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2783 for uniNo, uniPort := range dh.uniEntityMap {
2784 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002785
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2787 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2788 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2789 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002790 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002791 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002792 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002793 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002794 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 PortNo: port.PortNo,
2796 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002797 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 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 -04002799 }
2800 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002801 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002803 }
2804
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002805 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002806 }
2807}
2808
2809// ONU_Active/Inactive announcement on system KAFKA bus
2810// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002812 var de voltha.DeviceEvent
2813 eventContext := make(map[string]string)
2814 //Populating event context
2815 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002816 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002817 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002818 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002819 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002820 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 +00002821 }
2822 oltSerialNumber := parentDevice.SerialNumber
2823
2824 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2825 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2826 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302827 eventContext["olt-serial-number"] = oltSerialNumber
2828 eventContext["device-id"] = aDeviceID
2829 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002830 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002831 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2832 deviceEntry.MutexPersOnuConfig.RLock()
2833 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2834 deviceEntry.MutexPersOnuConfig.RUnlock()
2835 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2836 deviceEntry.MutexPersOnuConfig.RLock()
2837 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2838 deviceEntry.MutexPersOnuConfig.RUnlock()
2839 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002840 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2841 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2842 } else {
2843 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2844 log.Fields{"device-id": aDeviceID})
2845 return
2846 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002847
2848 /* Populating device event body */
2849 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302850 de.ResourceId = aDeviceID
2851 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002852 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2853 de.Description = fmt.Sprintf("%s Event - %s - %s",
2854 cEventObjectType, cOnuActivatedEvent, "Raised")
2855 } else {
2856 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2857 de.Description = fmt.Sprintf("%s Event - %s - %s",
2858 cEventObjectType, cOnuActivatedEvent, "Cleared")
2859 }
2860 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002861 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2862 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302863 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002864 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002865 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302866 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002867}
2868
Himani Chawla4d908332020-08-31 12:30:20 +05302869// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002870func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2871 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002872 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302873 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002874 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002875 sFsmName = "LockStateFSM"
2876 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002878 sFsmName = "UnLockStateFSM"
2879 }
mpagenko3af1f032020-06-10 08:53:41 +00002880
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002881 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002882 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002884 return
2885 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002886 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002887 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302888 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002889 dh.pLockStateFsm = pLSFsm
2890 } else {
2891 dh.pUnlockStateFsm = pLSFsm
2892 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002894 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002896 }
2897}
2898
2899// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002901 /* Uni Port lock/unlock procedure -
2902 ***** should run via 'adminDone' state and generate the argument requested event *****
2903 */
2904 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302905 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002906 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002907 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2908 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2910 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002911 }
2912 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002913 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002914 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2915 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2917 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002918 }
2919 }
2920 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2922 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002923 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002924 // maybe try a FSM reset and then again ... - TODO!!!
2925 } else {
2926 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002929 }
2930 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002933 // maybe try a FSM reset and then again ... - TODO!!!
2934 }
2935 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002937 // maybe try a FSM reset and then again ... - TODO!!!
2938 }
2939}
2940
mpagenko80622a52021-02-09 16:53:23 +00002941// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002942// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002945 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002947 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002948 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002949 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002950 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002952 sFsmName, chUpgradeFsm)
2953 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002955 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2957 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002958 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002959 // maybe try a FSM reset and then again ... - TODO!!!
2960 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2961 }
mpagenko59862f02021-10-11 08:53:18 +00002962 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002963 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2964 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002965 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2966 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002967 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002969 } else {
2970 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002971 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002972 // maybe try a FSM reset and then again ... - TODO!!!
2973 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2974 }
2975 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002977 // maybe try a FSM reset and then again ... - TODO!!!
2978 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2979 }
2980 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002982 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2983 }
2984 return nil
2985}
2986
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002987// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2988func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002989 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002991 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002992 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2993 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002994 dh.pLastUpgradeImageState = apImageState
2995 dh.lockUpgradeFsm.Unlock()
2996 //signal upgradeFsm removed using non-blocking channel send
2997 select {
2998 case dh.upgradeFsmChan <- struct{}{}:
2999 default:
3000 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003001 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003002 }
mpagenko80622a52021-02-09 16:53:23 +00003003}
3004
mpagenko15ff4a52021-03-02 10:09:20 +00003005// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3006func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003008 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003010 return
3011 }
3012
3013 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003014 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003015 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003016 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3017 dh.lockUpgradeFsm.RUnlock()
3018 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3019 return
3020 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003022 if pUpgradeStatemachine != nil {
3023 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3024 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 UpgradeState := pUpgradeStatemachine.Current()
3026 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3027 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3028 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003029 // 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 +00003030 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003031 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3032 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003033 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003034 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003036 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3037 dh.upgradeCanceled = true
3038 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3039 }
mpagenko15ff4a52021-03-02 10:09:20 +00003040 return
3041 }
mpagenko59862f02021-10-11 08:53:18 +00003042 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3044 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003045 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003046 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003047 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3048 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003049 return
3050 }
3051 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003052 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003053 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003054 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3055 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003056 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3057 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003058 return
3059 }
3060 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003062 }
3063 } else {
3064 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 +00003065 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003066 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3067 dh.upgradeCanceled = true
3068 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3069 }
mpagenko1f8e8822021-06-25 14:10:21 +00003070 }
mpagenko15ff4a52021-03-02 10:09:20 +00003071 return
3072 }
mpagenko59862f02021-10-11 08:53:18 +00003073 dh.lockUpgradeFsm.RUnlock()
3074 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3075 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003076 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3077 dh.upgradeCanceled = true
3078 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3079 }
mpagenko59862f02021-10-11 08:53:18 +00003080 return
3081 }
3082 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3083 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3084 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3085 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3086 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3087 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3088 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003089 }
mpagenko15ff4a52021-03-02 10:09:20 +00003090 }
3091 }
3092 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003094 }
mpagenko59862f02021-10-11 08:53:18 +00003095 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003096}
3097
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098//SetBackend provides a DB backend for the specified path on the existing KV client
3099func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003100
3101 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003102 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003103 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003104 kvbackend := &db.Backend{
3105 Client: dh.pOpenOnuAc.kvClient,
3106 StoreType: dh.pOpenOnuAc.KVStoreType,
3107 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003108 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003109 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3110 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003111
mpagenkoaf801632020-07-03 10:00:42 +00003112 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003113}
khenaidoo7d3c5582021-08-11 18:09:44 -04003114func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003116
mpagenkodff5dda2020-08-28 11:52:01 +00003117 for _, field := range flow.GetOfbFields(apFlowItem) {
3118 switch field.Type {
3119 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3120 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003122 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3123 }
mpagenko01e726e2020-10-23 09:45:29 +00003124 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003125 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3126 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303127 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303129 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3130 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003131 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3132 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003133 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303135 return
mpagenkodff5dda2020-08-28 11:52:01 +00003136 }
3137 }
mpagenko01e726e2020-10-23 09:45:29 +00003138 */
mpagenkodff5dda2020-08-28 11:52:01 +00003139 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3140 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303141 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003142 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303143 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003144 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303145 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003146 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303148 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003149 }
3150 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3151 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303152 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003153 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003154 "PCP": loAddPcp})
3155 }
3156 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3157 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003159 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3160 }
3161 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3162 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003163 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003164 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3165 }
3166 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3167 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003168 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003169 "IPv4-DST": field.GetIpv4Dst()})
3170 }
3171 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3172 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003174 "IPv4-SRC": field.GetIpv4Src()})
3175 }
3176 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3177 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003179 "Metadata": field.GetTableMetadata()})
3180 }
3181 /*
3182 default:
3183 {
3184 //all other entires ignored
3185 }
3186 */
3187 }
3188 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303189}
mpagenkodff5dda2020-08-28 11:52:01 +00003190
khenaidoo7d3c5582021-08-11 18:09:44 -04003191func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003192 for _, action := range flow.GetActions(apFlowItem) {
3193 switch action.Type {
3194 /* not used:
3195 case of.OfpActionType_OFPAT_OUTPUT:
3196 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003198 "Output": action.GetOutput()})
3199 }
3200 */
3201 case of.OfpActionType_OFPAT_PUSH_VLAN:
3202 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003203 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003204 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3205 }
3206 case of.OfpActionType_OFPAT_SET_FIELD:
3207 {
3208 pActionSetField := action.GetSetField()
3209 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003210 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003211 "OxcmClass": pActionSetField.Field.OxmClass})
3212 }
3213 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303214 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003215 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303216 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003217 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303218 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003219 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303220 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003221 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003223 "Type": pActionSetField.Field.GetOfbField().Type})
3224 }
3225 }
3226 /*
3227 default:
3228 {
3229 //all other entires ignored
3230 }
3231 */
3232 }
3233 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303234}
3235
3236//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003238 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303239 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3240 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3241 var loAddPcp, loSetPcp uint8
3242 var loIPProto uint32
3243 /* the TechProfileId is part of the flow Metadata - compare also comment within
3244 * OLT-Adapter:openolt_flowmgr.go
3245 * Metadata 8 bytes:
3246 * Most Significant 2 Bytes = Inner VLAN
3247 * Next 2 Bytes = Tech Profile ID(TPID)
3248 * Least Significant 4 Bytes = Port ID
3249 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3250 * subscriber related flows.
3251 */
3252
dbainbri4d3a0dc2020-12-02 00:33:42 +00003253 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303254 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003255 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003256 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003257 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303258 }
mpagenko551a4d42020-12-08 18:09:20 +00003259 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003260 loCookie := apFlowItem.GetCookie()
3261 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003262 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003263 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303264
dbainbri4d3a0dc2020-12-02 00:33:42 +00003265 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003266 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303267 if loIPProto == 2 {
3268 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3269 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003270 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303272 return nil
3273 }
mpagenko01e726e2020-10-23 09:45:29 +00003274 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003275 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003276
3277 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003278 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003280 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3281 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3282 //TODO!!: Use DeviceId within the error response to rwCore
3283 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003284 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003285 }
3286 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003287 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003288 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3289 } else {
3290 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3291 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3292 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303293 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003294 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003295 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003296 }
mpagenko9a304ea2020-12-16 15:54:01 +00003297
khenaidoo42dcdfd2021-10-19 17:34:12 -04003298 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003299 if apFlowMetaData != nil {
3300 meter = apFlowMetaData.Meters[0]
3301 }
mpagenkobc4170a2021-08-17 16:42:10 +00003302 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3303 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3304 // when different rules are requested concurrently for the same uni
3305 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3306 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3307 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003308 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3309 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003310 //SetUniFlowParams() may block on some rule that is suspended-to-add
3311 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003312 // Also the error is returned to caller via response channel
3313 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3314 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003315 dh.lockVlanConfig.RUnlock()
3316 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003317 return
mpagenkodff5dda2020-08-28 11:52:01 +00003318 }
mpagenkobc4170a2021-08-17 16:42:10 +00003319 dh.lockVlanConfig.RUnlock()
3320 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003321 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003322 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003323 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003324 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003325 if err != nil {
3326 *respChan <- err
3327 }
mpagenko01e726e2020-10-23 09:45:29 +00003328}
3329
3330//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003331func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003332 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3333 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3334 //no extra check is done on the rule parameters
3335 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3336 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3337 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3338 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003339 // - 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 +00003340 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003341 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003342
3343 /* TT related temporary workaround - should not be needed anymore
3344 for _, field := range flow.GetOfbFields(apFlowItem) {
3345 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3346 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003347 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003348 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3349 if loIPProto == 2 {
3350 // 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 +00003351 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003352 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003353 return nil
3354 }
3355 }
3356 } //for all OfbFields
3357 */
3358
mpagenko9a304ea2020-12-16 15:54:01 +00003359 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003360 dh.lockVlanConfig.RLock()
3361 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003362 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3363 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003364 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3365 return
mpagenko01e726e2020-10-23 09:45:29 +00003366 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003367 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003368 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003369 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003370 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003371 // Push response on the response channel
3372 if respChan != nil {
3373 // 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
3374 select {
3375 case *respChan <- nil:
3376 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3377 default:
3378 }
3379 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003381}
3382
Himani Chawla26e555c2020-08-31 12:30:20 +05303383// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003384// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003385// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003386func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003387 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003389
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003391 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3393 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003394 }
3395
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003396 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3397 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003398 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003399 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003400 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3401 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3403 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003404 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003405 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3406 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003407 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3408 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003409 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003410 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303411 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003412 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003413 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3414 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003415 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003416 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003417 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3418 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003419 }
3420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003421 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003422 "device-id": dh.DeviceID})
3423 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003424 }
3425 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003426 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3428 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003429 }
3430 return nil
3431}
3432
mpagenkofc4f56e2020-11-04 17:17:49 +00003433//VerifyVlanConfigRequest checks on existence of a given uniPort
3434// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003435func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003436 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003437 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003438 for _, uniPort := range dh.uniEntityMap {
3439 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003440 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003441 pCurrentUniPort = uniPort
3442 break //found - end search loop
3443 }
3444 }
3445 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003446 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003447 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003448 return
3449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003450 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003451}
3452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003453//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3454func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003455 //TODO!! verify and start pending flow configuration
3456 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3457 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003458
3459 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003460 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003461 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003462 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003464 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003465 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003466 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003467 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3468 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003469 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003470 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003471 } else {
3472 /***** UniVlanConfigFsm continued */
3473 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3475 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003476 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003477 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3478 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003479 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003480 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003481 } else {
3482 /***** UniVlanConfigFsm continued */
3483 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3485 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003486 }
mpagenkodff5dda2020-08-28 11:52:01 +00003487 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003488 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003489 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3490 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003491 }
3492 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003493 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 +00003494 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3495 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003496 }
3497 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003498 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003499 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003500 }
mpagenkof1fc3862021-02-16 10:09:52 +00003501 } else {
3502 dh.lockVlanConfig.RUnlock()
3503 }
mpagenkodff5dda2020-08-28 11:52:01 +00003504}
3505
3506//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3507// 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 +00003508func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003509 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003511 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003512 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003513 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003514 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003515}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003516
mpagenkof1fc3862021-02-16 10:09:52 +00003517//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003518func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003519 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3520 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3521 // obviously then parallel processing on the cancel must be avoided
3522 // deadline context to ensure completion of background routines waited for
3523 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3524 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3525 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3526
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003528 var wg sync.WaitGroup
3529 wg.Add(1) // for the 1 go routine to finish
3530
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003532 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3533
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003534 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003535}
3536
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003537//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003538//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3540 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003541
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003542 if dh.IsReconciling() {
3543 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003544 return nil
3545 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003546 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003547
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003549 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3551 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003552 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003553 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003554
mpagenkof1fc3862021-02-16 10:09:52 +00003555 if aWriteToKvStore {
3556 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3557 }
3558 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003559}
3560
dbainbri4d3a0dc2020-12-02 00:33:42 +00003561func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003562 defer cancel() //ensure termination of context (may be pro forma)
3563 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003564 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003565 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003566}
3567
mpagenkoe4782082021-11-25 12:04:26 +00003568//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3569// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3570func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3571 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3572 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3573 dh.mutexDeviceReason.Lock()
3574 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003575 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003576 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003577 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003578 DeviceId: dh.DeviceID,
3579 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003580 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003581 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003582 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003583 return err
3584 }
mpagenkoe4782082021-11-25 12:04:26 +00003585 } else {
3586 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 +00003587 }
mpagenkoe4782082021-11-25 12:04:26 +00003588 dh.deviceReason = deviceReason
3589 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3590 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003591 return nil
3592}
3593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003594func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3595 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003596 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003597 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3598 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003599 }
mpagenkof1fc3862021-02-16 10:09:52 +00003600 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003601}
3602
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003603// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003604// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003605func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3606 dh.lockDevice.RLock()
3607 defer dh.lockDevice.RUnlock()
3608 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003609 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003610 }
3611 return 0, errors.New("error-fetching-uni-port")
3612}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003613
3614// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003615func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3616 var errorsList []error
3617 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 -08003618
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003619 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3620 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3621 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3622
3623 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3624 // successfully.
3625 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3626 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3627 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003628 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 -08003629 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003630 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003631 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003632 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003633}
3634
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003635func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3636 var err error
3637 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003638 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003639
3640 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003642 errorsList = append(errorsList, err)
3643 }
3644 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003645 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003646
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003647 return errorsList
3648}
3649
3650func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3651 var err error
3652 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003653 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003654 // Check if group metric related config is updated
3655 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003656 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3657 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3658 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003659
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 if ok && m.Frequency != v.GroupFreq {
3661 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003662 errorsList = append(errorsList, err)
3663 }
3664 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003665 if ok && m.Enabled != v.Enabled {
3666 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003667 errorsList = append(errorsList, err)
3668 }
3669 }
3670 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003671 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003672 return errorsList
3673}
3674
3675func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3676 var err error
3677 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003678 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003679 // Check if standalone metric related config is updated
3680 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003681 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3682 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3683 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003685 if ok && m.Frequency != v.SampleFreq {
3686 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003687 errorsList = append(errorsList, err)
3688 }
3689 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690 if ok && m.Enabled != v.Enabled {
3691 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003692 errorsList = append(errorsList, err)
3693 }
3694 }
3695 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003696 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003697 return errorsList
3698}
3699
3700// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003701func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003702 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003703
3704 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303706 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003707 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003708 // Initialize the next metric collection time.
3709 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3710 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003711 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003712 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003713 for {
3714 select {
3715 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003716 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003717 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003718 // Stop the L2 PM FSM
3719 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003720 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3721 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3722 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003723 }
3724 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003725 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003726 }
3727 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003728 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3729 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003730 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003731 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3732 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003733 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003734
Girish Gowdrae09a6202021-01-12 18:10:59 -08003735 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003736 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3737 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3738 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3739 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3740 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003741 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003742 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003743 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003744 } else {
3745 if dh.pmConfigs.Grouped { // metrics are managed as a group
3746 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003747 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003748
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003749 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3750 // 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 -08003751 // 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 +00003752 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3753 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003754 }
3755 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003756 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3757 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3758 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3759 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003760 }
3761 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003762 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003763
3764 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003765 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3766 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3767 // 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 -08003768 // 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 +00003769 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3770 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003771 }
3772 }
3773 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003774 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3775 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3776 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3777 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003778 }
3779 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003780 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003781 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003782 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003783 } */
3784 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003785 }
3786 }
3787}
kesavandfdf77632021-01-26 23:40:33 -05003788
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003789func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3792 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003793}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003794
Himani Chawla43f95ff2021-06-03 00:24:12 +05303795func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3796 if dh.pOnuMetricsMgr == nil {
3797 return &extension.SingleGetValueResponse{
3798 Response: &extension.GetValueResponse{
3799 Status: extension.GetValueResponse_ERROR,
3800 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3801 },
3802 }
3803 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303804 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303805 return resp
3806}
3807
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003808func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3809 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003810 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003811 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003812 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003813}
3814
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003815func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003816 var pAdapterFsm *cmn.AdapterFsm
3817 //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 +00003818 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003819 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003820 {
mpagenkofbf577d2021-10-12 11:44:33 +00003821 if dh.pOnuOmciDevice != nil {
3822 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3823 } else {
3824 return true //FSM not active - so there is no activity on omci
3825 }
mpagenkof1fc3862021-02-16 10:09:52 +00003826 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003827 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003828 {
mpagenkofbf577d2021-10-12 11:44:33 +00003829 if dh.pOnuOmciDevice != nil {
3830 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3831 } else {
3832 return true //FSM not active - so there is no activity on omci
3833 }
mpagenkof1fc3862021-02-16 10:09:52 +00003834 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003835 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003836 {
mpagenkofbf577d2021-10-12 11:44:33 +00003837 if dh.pLockStateFsm != nil {
3838 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3839 } else {
3840 return true //FSM not active - so there is no activity on omci
3841 }
mpagenkof1fc3862021-02-16 10:09:52 +00003842 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003843 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003844 {
mpagenkofbf577d2021-10-12 11:44:33 +00003845 if dh.pUnlockStateFsm != nil {
3846 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3847 } else {
3848 return true //FSM not active - so there is no activity on omci
3849 }
mpagenkof1fc3862021-02-16 10:09:52 +00003850 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003851 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003852 {
mpagenkofbf577d2021-10-12 11:44:33 +00003853 if dh.pOnuMetricsMgr != nil {
3854 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003855 } else {
3856 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003857 }
3858 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003859 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003860 {
3861 dh.lockUpgradeFsm.RLock()
3862 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003863 if dh.pOnuUpradeFsm != nil {
3864 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3865 } else {
3866 return true //FSM not active - so there is no activity on omci
3867 }
mpagenko80622a52021-02-09 16:53:23 +00003868 }
mpagenkof1fc3862021-02-16 10:09:52 +00003869 default:
3870 {
3871 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003872 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003873 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003874 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003875 }
mpagenkofbf577d2021-10-12 11:44:33 +00003876 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3877 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3878 }
3879 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003880}
3881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003882func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3883 for _, v := range dh.pOnuTP.PAniConfigFsm {
3884 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003885 return false
3886 }
3887 }
3888 return true
3889}
3890
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003891func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003892 dh.lockVlanConfig.RLock()
3893 defer dh.lockVlanConfig.RUnlock()
3894 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003895 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003896 return false
3897 }
3898 }
3899 return true //FSM not active - so there is no activity on omci
3900}
3901
3902func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3903 dh.lockVlanConfig.RLock()
3904 defer dh.lockVlanConfig.RUnlock()
3905 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003906 if v.PAdaptFsm.PFsm != nil {
3907 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003908 return true //there is at least one VLAN FSM with some active configuration
3909 }
3910 }
3911 }
3912 return false //there is no VLAN FSM with some active configuration
3913}
3914
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003915func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003916 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3917 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3918 return false
3919 }
3920 }
3921 // a further check is done to identify, if at least some data traffic related configuration exists
3922 // 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])
3923 return dh.checkUserServiceExists(ctx)
3924}
3925
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003926func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003927 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3928 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003929 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003930 // TODO: fatal error reset ONU, delete deviceHandler!
3931 return
3932 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003933 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3934 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003935}
3936
3937func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3938 dh.mutexCollectorFlag.Lock()
3939 dh.collectorIsRunning = flagValue
3940 dh.mutexCollectorFlag.Unlock()
3941}
3942
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003944 dh.mutexCollectorFlag.RLock()
3945 flagValue := dh.collectorIsRunning
3946 dh.mutexCollectorFlag.RUnlock()
3947 return flagValue
3948}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303949
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303950func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3951 dh.mutextAlarmManagerFlag.Lock()
3952 dh.alarmManagerIsRunning = flagValue
3953 dh.mutextAlarmManagerFlag.Unlock()
3954}
3955
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003956func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303957 dh.mutextAlarmManagerFlag.RLock()
3958 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003959 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303960 dh.mutextAlarmManagerFlag.RUnlock()
3961 return flagValue
3962}
3963
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003964func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003965 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303966
3967 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003968 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303969 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303970 if stop := <-dh.stopAlarmManager; stop {
3971 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303972 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303973 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003974 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3975 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303976 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303977 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003978 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3979 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303980 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303981 }
3982}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003983
Girish Gowdrae95687a2021-09-08 16:30:58 -07003984func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3985 dh.mutexFlowMonitoringRoutineFlag.Lock()
3986 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003987 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003988 dh.isFlowMonitoringRoutineActive[uniID] = flag
3989}
3990
3991func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3992 dh.mutexFlowMonitoringRoutineFlag.RLock()
3993 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3994 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003995 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003996 return dh.isFlowMonitoringRoutineActive[uniID]
3997}
3998
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003999func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
4000 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004001
Maninder7961d722021-06-16 22:10:28 +05304002 connectStatus := voltha.ConnectStatus_UNREACHABLE
4003 operState := voltha.OperStatus_UNKNOWN
4004
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004006 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004007 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004008 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004009 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004010 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004011 logger.Debugw(ctx, "reconciling finished signal received",
4012 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4013 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4014 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4015 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4016 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4017 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4018 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4019 // However, a later refactoring of the functionality remains unaffected.
4020 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004021 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004022 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304023 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304025 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004026 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004027 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304028 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4030 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304031 operState = voltha.OperStatus_ACTIVE
4032 } else {
4033 operState = voltha.OperStatus_ACTIVATING
4034 }
4035 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004036 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4037 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4038 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304039 operState = voltha.OperStatus_DISCOVERED
4040 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004041 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004042 logger.Debugw(ctx, "Core DeviceStateUpdate",
4043 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304044 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004045 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004046 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004047 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004049 ConnStatus: connectStatus,
4050 OperStatus: operState,
4051 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304052 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004053 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304054 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004055 } else {
Maninderb5187552021-03-23 22:23:42 +05304056 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004057 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304058
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004059 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304060 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004061 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004062 } else {
4063 onuDevEntry.MutexPersOnuConfig.RLock()
4064 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4065 connectStatus = voltha.ConnectStatus_REACHABLE
4066 }
4067 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304068 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004069 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004070 }
mpagenko101ac942021-11-16 15:01:29 +00004071 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004072 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004073 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004074 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304075
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004076 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304077 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004078 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004079 } else {
4080 onuDevEntry.MutexPersOnuConfig.RLock()
4081 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4082 connectStatus = voltha.ConnectStatus_REACHABLE
4083 }
4084 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304085 }
4086
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004087 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304088
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004089 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004090 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004091 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004092 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004093 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004094
4095 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4096 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4097 } else {
4098 onuDevEntry.MutexReconciledTpInstances.Lock()
4099 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4100 onuDevEntry.MutexReconciledTpInstances.Unlock()
4101 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004102 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004103 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004104 dh.mutexReconcilingFlag.Lock()
4105 if skipOnuConfig {
4106 dh.reconciling = cSkipOnuConfigReconciling
4107 } else {
4108 dh.reconciling = cOnuConfigReconciling
4109 }
4110 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004111}
4112
mpagenko101ac942021-11-16 15:01:29 +00004113func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004114 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4115 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004116 dh.sendChReconcileFinished(success)
4117 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4118 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4119 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004120 } else {
mpagenko101ac942021-11-16 15:01:29 +00004121 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004122 }
4123}
4124
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004125func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004126 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004127 defer dh.mutexReconcilingFlag.RUnlock()
4128 return dh.reconciling != cNoReconciling
4129}
4130
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004131func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004132 dh.mutexReconcilingFlag.RLock()
4133 defer dh.mutexReconcilingFlag.RUnlock()
4134 return dh.reconciling == cSkipOnuConfigReconciling
4135}
4136
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004137func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4138 dh.mutexReconcilingFirstPassFlag.Lock()
4139 dh.reconcilingFirstPass = value
4140 dh.mutexReconcilingFirstPassFlag.Unlock()
4141}
4142
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004143func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4144 dh.mutexReconcilingReasonUpdate.Lock()
4145 dh.reconcilingReasonUpdate = value
4146 dh.mutexReconcilingReasonUpdate.Unlock()
4147}
4148
4149func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4150 dh.mutexReconcilingReasonUpdate.RLock()
4151 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4152 return dh.reconcilingReasonUpdate
4153}
4154
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004155func (dh *deviceHandler) getDeviceReason() uint8 {
4156 dh.mutexDeviceReason.RLock()
4157 value := dh.deviceReason
4158 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004159 return value
4160}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004161
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004162func (dh *deviceHandler) GetDeviceReasonString() string {
4163 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004164}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004165
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004166func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004167 dh.mutexReadyForOmciConfig.Lock()
4168 dh.readyForOmciConfig = flagValue
4169 dh.mutexReadyForOmciConfig.Unlock()
4170}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004171func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004172 dh.mutexReadyForOmciConfig.RLock()
4173 flagValue := dh.readyForOmciConfig
4174 dh.mutexReadyForOmciConfig.RUnlock()
4175 return flagValue
4176}
Maninder7961d722021-06-16 22:10:28 +05304177
4178func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004179 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304180 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004181 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304182 }
4183
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004184 logger.Debugw(ctx, "Core DeviceStateUpdate",
4185 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004186 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004187 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004188 ConnStatus: connectStatus,
4189 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4190 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304191 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304193 }
4194}
khenaidoo7d3c5582021-08-11 18:09:44 -04004195
4196/*
4197Helper functions to communicate with Core
4198*/
4199
4200func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4201 cClient, err := dh.coreClient.GetCoreServiceClient()
4202 if err != nil || cClient == nil {
4203 return nil, err
4204 }
4205 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4206 defer cancel()
4207 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4208 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4209}
4210
khenaidoo42dcdfd2021-10-19 17:34:12 -04004211func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004212 cClient, err := dh.coreClient.GetCoreServiceClient()
4213 if err != nil || cClient == nil {
4214 return err
4215 }
4216 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4217 defer cancel()
4218 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004219 logger.Debugw(subCtx, "device-updated-in-core",
4220 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004221 return err
4222}
4223
4224func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4225 cClient, err := dh.coreClient.GetCoreServiceClient()
4226 if err != nil || cClient == nil {
4227 return err
4228 }
4229 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4230 defer cancel()
4231 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004232 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4233 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004234 return err
4235}
4236
4237func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4238 cClient, err := dh.coreClient.GetCoreServiceClient()
4239 if err != nil || cClient == nil {
4240 return err
4241 }
4242 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4243 defer cancel()
4244 _, err = cClient.DeviceUpdate(subCtx, device)
4245 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4246 return err
4247}
4248
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004249func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004250 cClient, err := dh.coreClient.GetCoreServiceClient()
4251 if err != nil || cClient == nil {
4252 return err
4253 }
4254 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4255 defer cancel()
4256 _, err = cClient.PortCreated(subCtx, port)
4257 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4258 return err
4259}
4260
khenaidoo42dcdfd2021-10-19 17:34:12 -04004261func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004262 cClient, err := dh.coreClient.GetCoreServiceClient()
4263 if err != nil || cClient == nil {
4264 return err
4265 }
4266 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4267 defer cancel()
4268 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004269 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 -04004270 return err
4271}
4272
khenaidoo42dcdfd2021-10-19 17:34:12 -04004273func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004274 cClient, err := dh.coreClient.GetCoreServiceClient()
4275 if err != nil || cClient == nil {
4276 return err
4277 }
4278 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4279 defer cancel()
4280 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004281 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 -04004282 return err
4283}
4284
4285/*
4286Helper functions to communicate with parent adapter
4287*/
4288
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004289func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4290 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4291
4292 var request = ia.TechProfileInstanceRequestMessage{
4293 DeviceId: dh.DeviceID,
4294 TpInstancePath: aTpPath,
4295 ParentDeviceId: dh.parentID,
4296 ParentPonPort: dh.device.ParentPortNo,
4297 OnuId: dh.device.ProxyAddress.OnuId,
4298 UniId: uint32(aUniID),
4299 }
4300
4301 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004302 if err != nil || pgClient == nil {
4303 return nil, err
4304 }
4305 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4306 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004307 logger.Debugw(subCtx, "get-tech-profile-instance",
4308 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004309 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004310}
4311
Girish Gowdrae95687a2021-09-08 16:30:58 -07004312// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4313// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4314func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4315 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4316 dh.setFlowMonitoringIsRunning(uniID, true)
4317 for {
4318 select {
4319 // block on the channel to receive an incoming flow
4320 // process the flow completely before proceeding to handle the next flow
4321 case flowCb := <-dh.flowCbChan[uniID]:
4322 startTime := time.Now()
4323 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4324 respChan := make(chan error)
4325 if flowCb.addFlow {
4326 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4327 } else {
4328 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4329 }
4330 // Block on response and tunnel it back to the caller
4331 *flowCb.respChan <- <-respChan
4332 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4333 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4334 case <-dh.stopFlowMonitoringRoutine[uniID]:
4335 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4336 dh.setFlowMonitoringIsRunning(uniID, false)
4337 return
4338 }
4339 }
4340}
4341
kesavand011d5162021-11-25 19:21:06 +05304342func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4343 request.ParentDeviceId = dh.GetProxyAddressID()
4344 request.ChildDeviceId = dh.DeviceID
4345 request.ProxyAddress = dh.GetProxyAddress()
4346 request.ConnectStatus = common.ConnectStatus_REACHABLE
4347
4348 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4349 if err != nil || pgClient == nil {
4350 return err
4351 }
4352 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4353 defer cancel()
4354 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4355 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4356 if err != nil {
4357 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4358 }
4359 return err
4360}
4361
khenaidoo42dcdfd2021-10-19 17:34:12 -04004362func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004363 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4364 if err != nil || pgClient == nil {
4365 return err
4366 }
4367 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4368 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004369 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004370 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4371 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004372 logger.Errorw(ctx, "omci-failure",
4373 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4374 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004375 }
4376 return err
4377}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004378
4379// GetDeviceID - TODO: add comment
4380func (dh *deviceHandler) GetDeviceID() string {
4381 return dh.DeviceID
4382}
4383
4384// GetProxyAddressID - TODO: add comment
4385func (dh *deviceHandler) GetProxyAddressID() string {
4386 return dh.device.ProxyAddress.GetDeviceId()
4387}
4388
4389// GetProxyAddressType - TODO: add comment
4390func (dh *deviceHandler) GetProxyAddressType() string {
4391 return dh.device.ProxyAddress.GetDeviceType()
4392}
4393
4394// GetProxyAddress - TODO: add comment
4395func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4396 return dh.device.ProxyAddress
4397}
4398
4399// GetEventProxy - TODO: add comment
4400func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4401 return dh.EventProxy
4402}
4403
4404// GetOmciTimeout - TODO: add comment
4405func (dh *deviceHandler) GetOmciTimeout() int {
4406 return dh.pOpenOnuAc.omciTimeout
4407}
4408
4409// GetAlarmAuditInterval - TODO: add comment
4410func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4411 return dh.pOpenOnuAc.alarmAuditInterval
4412}
4413
4414// GetDlToOnuTimeout4M - TODO: add comment
4415func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4416 return dh.pOpenOnuAc.dlToOnuTimeout4M
4417}
4418
4419// GetUniEntityMap - TODO: add comment
4420func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4421 return &dh.uniEntityMap
4422}
4423
4424// GetPonPortNumber - TODO: add comment
4425func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4426 return &dh.ponPortNumber
4427}
4428
4429// GetUniVlanConfigFsm - TODO: add comment
4430func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004431 dh.lockVlanConfig.RLock()
4432 value := dh.UniVlanConfigFsmMap[uniID]
4433 dh.lockVlanConfig.RUnlock()
4434 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004435}
4436
4437// GetOnuAlarmManager - TODO: add comment
4438func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4439 return dh.pAlarmMgr
4440}
4441
4442// GetOnuMetricsManager - TODO: add comment
4443func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4444 return dh.pOnuMetricsMgr
4445}
4446
4447// GetOnuTP - TODO: add comment
4448func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4449 return dh.pOnuTP
4450}
4451
4452// GetBackendPathPrefix - TODO: add comment
4453func (dh *deviceHandler) GetBackendPathPrefix() string {
4454 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4455}
4456
4457// GetOnuIndication - TODO: add comment
4458func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4459 return dh.pOnuIndication
4460}
4461
4462// RLockMutexDeletionInProgressFlag - TODO: add comment
4463func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4464 dh.mutexDeletionInProgressFlag.RLock()
4465}
4466
4467// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4468func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4469 dh.mutexDeletionInProgressFlag.RUnlock()
4470}
4471
4472// GetDeletionInProgress - TODO: add comment
4473func (dh *deviceHandler) GetDeletionInProgress() bool {
4474 return dh.deletionInProgress
4475}
4476
4477// GetPmConfigs - TODO: add comment
4478func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4479 return dh.pmConfigs
4480}
4481
4482// GetDeviceType - TODO: add comment
4483func (dh *deviceHandler) GetDeviceType() string {
4484 return dh.DeviceType
4485}
4486
4487// GetLogicalDeviceID - TODO: add comment
4488func (dh *deviceHandler) GetLogicalDeviceID() string {
4489 return dh.logicalDeviceID
4490}
4491
4492// GetDevice - TODO: add comment
4493func (dh *deviceHandler) GetDevice() *voltha.Device {
4494 return dh.device
4495}
4496
4497// GetMetricsEnabled - TODO: add comment
4498func (dh *deviceHandler) GetMetricsEnabled() bool {
4499 return dh.pOpenOnuAc.MetricsEnabled
4500}
4501
4502// InitPmConfigs - TODO: add comment
4503func (dh *deviceHandler) InitPmConfigs() {
4504 dh.pmConfigs = &voltha.PmConfigs{}
4505}
4506
4507// GetUniPortMask - TODO: add comment
4508func (dh *deviceHandler) GetUniPortMask() int {
4509 return dh.pOpenOnuAc.config.UniPortMask
4510}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004511
4512func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4513 tpPathFound := false
4514 for _, tpPath := range aTpPathMap {
4515 if tpPath != "" {
4516 tpPathFound = true
4517 }
4518 }
4519 return tpPathFound
4520}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004521
4522// PrepareForGarbageCollection - remove references to prepare for garbage collection
4523func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4524 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4525
4526 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4527 // first let the objects rest for some time to give all asynchronously started
4528 // cleanup routines a chance to come to an end
4529 time.Sleep(5 * time.Second)
4530
4531 if dh.pOnuTP != nil {
4532 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4533 }
4534 if dh.pOnuMetricsMgr != nil {
4535 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4536 }
4537 if dh.pAlarmMgr != nil {
4538 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4539 }
4540 if dh.pSelfTestHdlr != nil {
4541 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4542 }
4543 if dh.pLockStateFsm != nil {
4544 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4545 }
4546 if dh.pUnlockStateFsm != nil {
4547 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4548 }
4549 if dh.pOnuUpradeFsm != nil {
4550 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4551 }
4552 if dh.pOnuOmciDevice != nil {
4553 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4554 }
4555 for k, v := range dh.UniVlanConfigFsmMap {
4556 v.PrepareForGarbageCollection(ctx, aDeviceID)
4557 delete(dh.UniVlanConfigFsmMap, k)
4558 }
4559 dh.pOnuOmciDevice = nil
4560 dh.pOnuTP = nil
4561 dh.pOnuMetricsMgr = nil
4562 dh.pAlarmMgr = nil
4563 dh.pSelfTestHdlr = nil
4564 dh.pLockStateFsm = nil
4565 dh.pUnlockStateFsm = nil
4566 dh.pOnuUpradeFsm = nil
4567}