blob: b4574aec3f3efa7dd50957610cce70f28c0034da [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package core provides the utility for onu devices, flows and statistics
18package core
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000019
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
khenaidoo7d3c5582021-08-11 18:09:44 -040028 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/config"
mpagenko1f8e8822021-06-25 14:10:21 +000029
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000032 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040033 "github.com/opencord/voltha-lib-go/v7/pkg/db"
34 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
35 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
36 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
37 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Mahir Gunyelcb128ae2021-10-06 09:42:05 -070038 platform "github.com/opencord/voltha-lib-go/v7/pkg/platform"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000039 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
40 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
41 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
42 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
43 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
44 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
45 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
46 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
kesavand011d5162021-11-25 19:21:06 +053047 "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040049 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040050 "github.com/opencord/voltha-protos/v5/go/extension"
Holger Hildebrandt9afc1582021-11-30 16:10:19 +000051 "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo42dcdfd2021-10-19 17:34:12 -040052 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000056 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040057 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000058)
59
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060const (
mpagenko101ac942021-11-16 15:01:29 +000061 //constants for reconcile flow check channel
62 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
63 cWaitReconcileFlowAbortOnError = 0xFFFE
64 cWaitReconcileFlowNoActivity = 0xFFFF
65)
66
67const (
68 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000069 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000070)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000071
mpagenko1cc3cb42020-07-27 15:24:38 +000072const (
mpagenko44bd8362021-11-15 11:40:05 +000073 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
74 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
75 // as long as such is not available by the libraries - use this workaround
76 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
77)
78
79const (
mpagenko1cc3cb42020-07-27 15:24:38 +000080 // events of Device FSM
81 devEvDeviceInit = "devEvDeviceInit"
82 devEvGrpcConnected = "devEvGrpcConnected"
83 devEvGrpcDisconnected = "devEvGrpcDisconnected"
84 devEvDeviceUpInd = "devEvDeviceUpInd"
85 devEvDeviceDownInd = "devEvDeviceDownInd"
86)
87const (
88 // states of Device FSM
89 devStNull = "devStNull"
90 devStDown = "devStDown"
91 devStInit = "devStInit"
92 devStConnected = "devStConnected"
93 devStUp = "devStUp"
94)
95
Holger Hildebrandt24d51952020-05-04 14:03:42 +000096//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
97const (
Himani Chawla4d908332020-08-31 12:30:20 +053098 pon = voltha.EventSubCategory_PON
99 //olt = voltha.EventSubCategory_OLT
100 //ont = voltha.EventSubCategory_ONT
101 //onu = voltha.EventSubCategory_ONU
102 //nni = voltha.EventSubCategory_NNI
103 //service = voltha.EventCategory_SERVICE
104 //security = voltha.EventCategory_SECURITY
105 equipment = voltha.EventCategory_EQUIPMENT
106 //processing = voltha.EventCategory_PROCESSING
107 //environment = voltha.EventCategory_ENVIRONMENT
108 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000109)
110
111const (
112 cEventObjectType = "ONU"
113)
114const (
115 cOnuActivatedEvent = "ONU_ACTIVATED"
116)
117
mpagenkof1fc3862021-02-16 10:09:52 +0000118type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000120 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000123var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
124 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
125 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
126 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
127 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
128 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
129 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
130 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
131 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000132}
133
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000134const (
135 cNoReconciling = iota
136 cOnuConfigReconciling
137 cSkipOnuConfigReconciling
138)
139
Girish Gowdrae95687a2021-09-08 16:30:58 -0700140// FlowCb is the flow control block containing flow add/delete information along with a response channel
141type FlowCb struct {
142 ctx context.Context // Flow handler context
143 addFlow bool // if true flow to be added, else removed
144 flowItem *of.OfpFlowStats
145 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400146 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700147 respChan *chan error // channel to report the Flow handling error
148}
149
Himani Chawla6d2ae152020-09-02 13:11:20 +0530150//deviceHandler will interact with the ONU ? device.
151type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153 DeviceType string
154 adminState string
155 device *voltha.Device
156 logicalDeviceID string
157 ProxyAddressID string
158 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530159 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000160 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000161
khenaidoo7d3c5582021-08-11 18:09:44 -0400162 coreClient *vgrpc.Client
163 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000164
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800165 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400166 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800167
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000168 pOpenOnuAc *OpenONUAC
169 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530170 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000171 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000172 pOnuOmciDevice *mib.OnuDeviceEntry
173 pOnuTP *avcfg.OnuUniTechProf
174 pOnuMetricsMgr *pmmgr.OnuMetricsManager
175 pAlarmMgr *almgr.OnuAlarmManager
176 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000177 exitChannel chan int
178 lockDevice sync.RWMutex
179 pOnuIndication *oop.OnuIndication
180 deviceReason uint8
181 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000182 pLockStateFsm *uniprt.LockStateFsm
183 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 //flowMgr *OpenOltFlowMgr
186 //eventMgr *OpenOltEventMgr
187 //resourceMgr *rsrcMgr.OpenOltResourceMgr
188
189 //discOnus sync.Map
190 //onus sync.Map
191 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000192 collectorIsRunning bool
193 mutexCollectorFlag sync.RWMutex
194 stopCollector chan bool
195 alarmManagerIsRunning bool
196 mutextAlarmManagerFlag sync.RWMutex
197 stopAlarmManager chan bool
198 stopHeartbeatCheck chan bool
199 uniEntityMap cmn.OnuUniPortMap
200 mutexKvStoreContext sync.Mutex
201 lockVlanConfig sync.RWMutex
202 lockVlanAdd sync.RWMutex
203 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
204 lockUpgradeFsm sync.RWMutex
205 pOnuUpradeFsm *swupg.OnuUpgradeFsm
206 upgradeCanceled bool
207 reconciling uint8
208 mutexReconcilingFlag sync.RWMutex
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000209 reconcilingFirstPass bool
210 mutexReconcilingFirstPassFlag sync.RWMutex
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000211 reconcilingReasonUpdate bool
212 mutexReconcilingReasonUpdate sync.RWMutex
mpagenko101ac942021-11-16 15:01:29 +0000213 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
214 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
215 reconcileExpiryComplete time.Duration
216 reconcileExpiryVlanConfig time.Duration
217 mutexReadyForOmciConfig sync.RWMutex
218 readyForOmciConfig bool
219 deletionInProgress bool
220 mutexDeletionInProgressFlag sync.RWMutex
221 pLastUpgradeImageState *voltha.ImageState
222 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700223
224 flowCbChan []chan FlowCb
225 mutexFlowMonitoringRoutineFlag sync.RWMutex
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300226 mutexForDisableDeviceRequested sync.RWMutex
Girish Gowdrae95687a2021-09-08 16:30:58 -0700227 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
228 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300229 disableDeviceRequested bool // this flag identify ONU received disable request or not
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400233func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530234 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400235 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400237 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000239 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.DeviceType = cloned.Type
241 dh.adminState = "up"
242 dh.device = cloned
243 dh.pOpenOnuAc = adapter
244 dh.exitChannel = make(chan int, 1)
245 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000246 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000247 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530249 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530250 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000251 dh.stopHeartbeatCheck = make(chan bool, 2)
252 //dh.metrics = pmmetrics.NewPmMetrics(cloned.Id, pmmetrics.Frequency(150), pmmetrics.FrequencyOverride(false), pmmetrics.Grouped(false), pmmetrics.Metrics(pmNames))
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000255 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000256 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000257 dh.lockUpgradeFsm = sync.RWMutex{}
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300258 dh.mutexForDisableDeviceRequested = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000260 dh.reconciling = cNoReconciling
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000261 dh.reconcilingReasonUpdate = false
Holger Hildebrandt7741f272022-01-18 08:17:39 +0000262 dh.reconcilingFirstPass = true
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300263 dh.disableDeviceRequested = false
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000264 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000265 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
266 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
267 if rECSeconds < 2 {
268 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
269 rECSeconds = 2
270 }
271 rEVCSeconds := rECSeconds / 2
272 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000273 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000274 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000275 dh.pLastUpgradeImageState = &voltha.ImageState{
276 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
277 Reason: voltha.ImageState_UNKNOWN_ERROR,
278 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
279 }
280 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800282 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
283 dh.pmConfigs = cloned.PmConfigs
284 } /* else {
285 // will be populated when onu_metrics_mananger is initialized.
286 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800287
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000288 // Device related state machine
289 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000290 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000291 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000292 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
293 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
294 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
295 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
296 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 },
298 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000299 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
300 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
301 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
302 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
303 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
304 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
305 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
306 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307 },
308 )
mpagenkoaf801632020-07-03 10:00:42 +0000309
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310 return &dh
311}
312
Himani Chawla6d2ae152020-09-02 13:11:20 +0530313// start save the device to the data model
314func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000315 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316 // Add the initial device to the local model
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000317 logger.Debugw(ctx, "device-handler-started", log.Fields{"device": dh.device})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318}
319
Himani Chawla4d908332020-08-31 12:30:20 +0530320/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000323 logger.Debug("stopping-device-handler")
324 dh.exitChannel <- 1
325}
Himani Chawla4d908332020-08-31 12:30:20 +0530326*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327
328// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530329// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330
Girish Gowdrae0140f02021-02-02 16:55:09 -0800331//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530332func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400333 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000336 if dh.pDeviceStateFsm.Is(devStNull) {
337 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000338 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"device-id": device.Id, "err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000339 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000340 logger.Debugw(ctx, "Device FSM: ", log.Fields{"device-id": device.Id, "state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800341 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
342 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800343 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400344 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800346 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800347 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000348 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000350 }
351
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000352}
353
khenaidoo42dcdfd2021-10-19 17:34:12 -0400354func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000355 /* msg print moved symmetrically to omci_cc, if wanted here as additional debug, than perhaps only based on additional debug setting!
Himani Chawla26e555c2020-08-31 12:30:20 +0530356 //assuming omci message content is hex coded!
357 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000358 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000359 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000360 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000363 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000364 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000365 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000366 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"device-id": dh.DeviceID,
367 "rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000369 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
370 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530371}
372
khenaidoo42dcdfd2021-10-19 17:34:12 -0400373func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000376 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000377 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
379 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 if dh.pOnuTP == nil {
382 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 log.Fields{"device-id": dh.DeviceID})
385 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000387 if !dh.IsReadyForOmciConfig() {
388 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
389 "device-state": dh.GetDeviceReasonString()})
390 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000392 //previous state test here was just this one, now extended for more states to reject the SetRequest:
393 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
394 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
398 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 dh.pOnuTP.LockTpProcMutex()
400 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000401
mpagenko44bd8362021-11-15 11:40:05 +0000402 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000403 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000404 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 }
406 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +0000409 logger.Errorw(ctx, "error-parsing-tpid-from-tppath",
410 log.Fields{"device-id": dh.DeviceID, "err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800411 return err
412 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000413 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"device-id": dh.DeviceID,
414 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000415
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000416 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530417
Girish Gowdra50e56422021-06-01 16:46:04 -0700418 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400419 case *ia.TechProfileDownloadMessage_TpInstance:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000420 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"device-id": dh.DeviceID,
421 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700422 // if there has been some change for some uni TechProfilePath
423 //in order to allow concurrent calls to other dh instances we do not wait for execution here
424 //but doing so we can not indicate problems to the caller (who does what with that then?)
425 //by now we just assume straightforward successful execution
426 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
427 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530428
Girish Gowdra50e56422021-06-01 16:46:04 -0700429 // deadline context to ensure completion of background routines waited for
430 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
431 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
432 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000433
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700435
436 var wg sync.WaitGroup
437 wg.Add(1) // for the 1 go routine to finish
438 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700440 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
442 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 -0700443 return tpErr
444 }
445 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
446 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000447 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700448 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700450 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000451 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
452 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 -0700453 return kvErr
454 }
455 return nil
456 default:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000457 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"device-id": dh.DeviceID, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra50e56422021-06-01 16:46:04 -0700458 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700459 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530460 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000461 // no change, nothing really to do - return success
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +0000462 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"device-id": dh.DeviceID,
463 "uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530464 return nil
465}
466
khenaidoo42dcdfd2021-10-19 17:34:12 -0400467func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000468 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530469
470 if dh.pOnuTP == nil {
471 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000473 log.Fields{"device-id": dh.DeviceID})
474 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530475 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530476 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000477 dh.pOnuTP.LockTpProcMutex()
478 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530479
mpagenko0f543222021-11-03 16:24:14 +0000480 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
481 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
482 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000484 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485 }
486 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000487 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800488 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000489 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
490 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800491 return err
492 }
mpagenko0f543222021-11-03 16:24:14 +0000493 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
494 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000495 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000496
Mahir Gunyel9545be22021-07-04 15:53:16 -0700497 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000498 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499
Himani Chawla26e555c2020-08-31 12:30:20 +0530500}
501
khenaidoo42dcdfd2021-10-19 17:34:12 -0400502func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000503 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 +0000504
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
508 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530510 if dh.pOnuTP == nil {
511 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000512 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000513 log.Fields{"device-id": dh.DeviceID})
514 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530515 }
516
Himani Chawla26e555c2020-08-31 12:30:20 +0530517 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 dh.pOnuTP.LockTpProcMutex()
519 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000520
mpagenko0f543222021-11-03 16:24:14 +0000521 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
522 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
523 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000525 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 }
527 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700528 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000529 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800530 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000531 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
532 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800533 return err
534 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530536
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000537 var wg sync.WaitGroup
538 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
539 dctx, cancel := context.WithDeadline(context.Background(), deadline)
540 wg.Add(1)
541 logger.Debugw(ctx, "remove-tcont-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
542 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
543 dh.waitForCompletion(ctx, cancel, &wg, "DeleteTcont") //wait for background process to finish
544 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
545 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
546 return err
547 }
548
Mahir Gunyel9545be22021-07-04 15:53:16 -0700549 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000551
Mahir Gunyel9545be22021-07-04 15:53:16 -0700552}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000553
Mahir Gunyel9545be22021-07-04 15:53:16 -0700554func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
556 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700557 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000558 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
559 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530560 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700563 resourceName = "Gem"
564 } else {
565 resourceName = "Tcont"
566 }
567
568 // deadline context to ensure completion of background routines waited for
569 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
570 dctx, cancel := context.WithDeadline(context.Background(), deadline)
571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700573
574 var wg sync.WaitGroup
575 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700577 resource, entryID, &wg)
578 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
580 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700581 return err
582 }
583
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
585 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
586 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
587 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700588 var wg2 sync.WaitGroup
589 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
590 wg2.Add(1)
591 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt6ec9cc12022-01-24 15:47:52 +0000592 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 +0000593 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700594 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
596 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700597 return err
598 }
599 }
600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700602 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530603 return nil
604}
605
mpagenkodff5dda2020-08-28 11:52:01 +0000606//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400608 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400609 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700610 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
611 var errorsList []error
612 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000613 //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 +0000614 if apOfFlowChanges.ToRemove != nil {
615 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000616 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000617 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 "device-id": dh.DeviceID})
619 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700620 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000621 continue
622 }
623 flowInPort := flow.GetInPort(flowItem)
624 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000625 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
626 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700627 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000628 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000629 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000630 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000631 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000634 continue
635 } else {
636 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000638 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
639 loUniPort = uniPort
640 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000641 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000643 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700645 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000646 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000647 }
648 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
651 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700652
653 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
654 // Step1 : Fill flowControlBlock
655 // Step2 : Push the flowControlBlock to ONU channel
656 // Step3 : Wait on response channel for response
657 // Step4 : Return error value
658 startTime := time.Now()
659 respChan := make(chan error)
660 flowCb := FlowCb{
661 ctx: ctx,
662 addFlow: false,
663 flowItem: flowItem,
664 flowMetaData: nil,
665 uniPort: loUniPort,
666 respChan: &respChan,
667 }
668 dh.flowCbChan[loUniPort.UniID] <- flowCb
669 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
670 // Wait on the channel for flow handlers return value
671 retError = <-respChan
672 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
673 if retError != nil {
674 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
675 log.Fields{"device-id": dh.DeviceID, "error": retError})
676 errorsList = append(errorsList, retError)
677 continue
678 }
679 } else {
680 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
681 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000682 }
683 }
684 }
685 }
mpagenko01e726e2020-10-23 09:45:29 +0000686 if apOfFlowChanges.ToAdd != nil {
687 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
688 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000690 "device-id": dh.DeviceID})
691 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700692 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000693 continue
694 }
695 flowInPort := flow.GetInPort(flowItem)
696 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000697 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
698 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700699 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000700 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000701 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000702 } else if flowInPort == dh.ponPortNumber {
703 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000706 continue
707 } else {
708 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000709 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000710 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
711 loUniPort = uniPort
712 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000714 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000715 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000716 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700717 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000718 continue
mpagenko01e726e2020-10-23 09:45:29 +0000719 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000720 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
721 // if not, we just throw some error here to have an indication about that, if we really need to support that
722 // then we would need to create some means to activate the internal stored flows
723 // after the device gets active automatically (and still with its dependency to the TechProfile)
724 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
725 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000726 if !dh.IsReadyForOmciConfig() {
727 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
728 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700729 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
730 errorsList = append(errorsList, retError)
731 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000732 }
733
mpagenko01e726e2020-10-23 09:45:29 +0000734 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000735 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000736 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
737 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700738 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
739 // Step1 : Fill flowControlBlock
740 // Step2 : Push the flowControlBlock to ONU channel
741 // Step3 : Wait on response channel for response
742 // Step4 : Return error value
743 startTime := time.Now()
744 respChan := make(chan error)
745 flowCb := FlowCb{
746 ctx: ctx,
747 addFlow: true,
748 flowItem: flowItem,
749 flowMetaData: apFlowMetaData,
750 uniPort: loUniPort,
751 respChan: &respChan,
752 }
753 dh.flowCbChan[loUniPort.UniID] <- flowCb
754 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
755 // Wait on the channel for flow handlers return value
756 retError = <-respChan
757 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
758 if retError != nil {
759 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
760 log.Fields{"device-id": dh.DeviceID, "error": retError})
761 errorsList = append(errorsList, retError)
762 continue
763 }
764 } else {
765 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
766 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000767 }
768 }
769 }
770 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700771 if len(errorsList) > 0 {
772 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
773 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
774 }
775 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000776}
777
Himani Chawla6d2ae152020-09-02 13:11:20 +0530778//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000779//following are the expected device states after this activity:
780//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
781// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
783 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300784 dh.mutexForDisableDeviceRequested.Lock()
785 dh.disableDeviceRequested = true
786 dh.mutexForDisableDeviceRequested.Unlock()
mpagenko900ee4b2020-10-12 11:56:34 +0000787 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000788 //note that disableDevice sequences in some 'ONU active' state may yield also
789 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000790 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000791 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 //disable-device shall be just a UNi/ONU-G related admin state setting
793 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000794
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000796 // disable UNI ports/ONU
797 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
798 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000799 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000800 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000801 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000803 }
804 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000805 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000806 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000807 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400808 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000810 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400811 OperStatus: voltha.OperStatus_UNKNOWN,
812 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000813 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000815 }
mpagenko01e726e2020-10-23 09:45:29 +0000816 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000817
818 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
mpagenkoe4782082021-11-25 12:04:26 +0000819 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000820 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300821 }
822}
823
Himani Chawla6d2ae152020-09-02 13:11:20 +0530824//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000825func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
826 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000827
mpagenkoaa3afe92021-05-21 16:20:58 +0000828 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000829 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
830 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
831 // for real ONU's that should have nearly no influence
832 // Note that for real ONU's there is anyway a problematic situation with following sequence:
833 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
834 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
835 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000837
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000838 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000839 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +0300840 dh.mutexForDisableDeviceRequested.Lock()
841 dh.disableDeviceRequested = false
842 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000843 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000844 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000845 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000846 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000848 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300849}
850
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000852 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000853
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000854 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 return
858 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000860 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000862 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000864 }
mpagenko101ac942021-11-16 15:01:29 +0000865 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000866 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000867 }
Himani Chawla4d908332020-08-31 12:30:20 +0530868 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000869 pDevEntry.MutexPersOnuConfig.RLock()
870 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
871 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
872 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
873 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
874 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000875 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000876}
877
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000878func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000880
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000881 continueWithFlowConfig := false
882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000885 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000886 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
887 return continueWithFlowConfig
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 dh.pOnuTP.LockTpProcMutex()
890 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000891
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000893 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
895 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000896 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000898 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
899 return continueWithFlowConfig
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700902 techProfsFound := false
903 techProfInstLoadFailed := false
904outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000905 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000906 uniID := uniData.PersUniID
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000907 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000908 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000909 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000910 log.Fields{"uni-id": uniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000912 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000913 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
914 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000915 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000916 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000917 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700918 techProfsFound = true // set to true if we found TP once for any UNI port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000919 var iaTechTpInst ia.TechProfileDownloadMessage
920 var ok bool
Girish Gowdra041dcb32020-11-16 16:54:30 -0800921 for tpID := range uniData.PersTpPathMap {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000922 pDevEntry.MutexReconciledTpInstances.RLock()
923 if iaTechTpInst, ok = pDevEntry.ReconciledTpInstances[uniID][tpID]; !ok {
924 logger.Errorw(ctx, "reconciling - no reconciled tp instance available",
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000925 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID,
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000926 "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700927 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000928 pDevEntry.MutexReconciledTpInstances.RUnlock()
Girish Gowdra50e56422021-06-01 16:46:04 -0700929 break outerLoop
930 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000931 pDevEntry.MutexReconciledTpInstances.RUnlock()
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000932 continueWithFlowConfig = true // valid TP found - try flow configuration later
Girish Gowdra50e56422021-06-01 16:46:04 -0700933 var tpInst tech_profile.TechProfileInstance
934 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400935 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 tpInst = *techTpInst.TpInstance
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000937 logger.Debugw(ctx, "reconciling - received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000938 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700939 default: // do not support epon or other tech
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000940 logger.Errorw(ctx, "reconciling - unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
943 break outerLoop
944 }
945
Girish Gowdra041dcb32020-11-16 16:54:30 -0800946 // deadline context to ensure completion of background routines waited for
947 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
948 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000951 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800952 var wg sync.WaitGroup
953 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000956 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
957 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700958 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
959 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800960 }
mpagenko2dc896e2021-08-02 12:03:59 +0000961 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000962 if len(uniData.PersFlowParams) != 0 {
963 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000964 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000965 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000966 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 } // for all UNI entries from SOnuPersistentData
968 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
969 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000970 }
mpagenko2dc896e2021-08-02 12:03:59 +0000971
972 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
973 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000974
975 return continueWithFlowConfig
mpagenko2dc896e2021-08-02 12:03:59 +0000976}
977
978func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
979 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
980 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000981 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000983 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000984 return
985 }
mpagenko2dc896e2021-08-02 12:03:59 +0000986 if abTechProfInstLoadFailed {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000987 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadFailed, dh.IsReconcilingReasonUpdate())
mpagenko101ac942021-11-16 15:01:29 +0000988 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700989 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 } else if dh.IsSkipOnuConfigReconciling() {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +0000991 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, dh.IsReconcilingReasonUpdate())
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992 }
mpagenko2dc896e2021-08-02 12:03:59 +0000993 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000994 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000995 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +0000996 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000997 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000998}
999
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001000func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
1001 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001002
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001003 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004 if pDevEntry == nil {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00001005 logger.Errorw(ctx, "reconciling - no valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001006 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001007 return
1008 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 pDevEntry.MutexPersOnuConfig.RLock()
1011 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
1012 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001015 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001016 return
1017 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001019 var uniVlanConfigEntries []uint8
1020 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1021
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001023 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1024 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 continue
1028 }
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001029 if !dh.anyTpPathExists(uniData.PersTpPathMap) {
mpagenko101ac942021-11-16 15:01:29 +00001030 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001032 // It doesn't make sense to configure any flows if no TPs are available
1033 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001034 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1036 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001037 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001038 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001039
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001041 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001042 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001043 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1045 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001046 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 return
1048 }
mpagenko101ac942021-11-16 15:01:29 +00001049 //needed to split up function due to sca complexity
1050 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1051
mpagenko2dc896e2021-08-02 12:03:59 +00001052 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001053 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1055 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001056 // this can't be used as global finished reconciling flag because
1057 // assumes is getting called before the state machines for the last flow is completed,
1058 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1060 } // for all UNI entries from SOnuPersistentData
1061 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001062
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001063 if !flowsFound {
1064 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001065 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtb314f442021-11-24 12:03:10 +00001066 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001067 return
1068 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001069 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1070 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1071 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1072 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1073 log.Fields{"device-id": dh.DeviceID})
1074 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1075 if pDevEntry != nil {
1076 pDevEntry.SendChReconcilingFlowsFinished(ctx, true)
mpagenko101ac942021-11-16 15:01:29 +00001077 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001078 } else {
1079 logger.Errorw(ctx, "reconciling - timeout waiting for reconciling flows for all UNI's to be finished!",
1080 log.Fields{"device-id": dh.DeviceID})
1081 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1082 if pDevEntry != nil {
1083 pDevEntry.SendChReconcilingFlowsFinished(ctx, false)
1084 }
1085 return
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001086 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001087 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, dh.IsReconcilingReasonUpdate())
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001088}
1089
mpagenko101ac942021-11-16 15:01:29 +00001090func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1091 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1092 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1093 flowsProcessed := 0
1094 lastFlowToReconcile := false
1095 loUniID := apUniPort.UniID
1096 for _, flowData := range aPersFlowParam {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001097 if !(*apFlowsFound) {
1098 *apFlowsFound = true
1099 syncChannel := make(chan struct{})
1100 // start go routine with select() on reconciling vlan config channel before
1101 // starting vlan config reconciling process to prevent loss of any signal
1102 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1103 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1104 //block until the wait routine is really blocked on channel input
1105 // in order to prevent to early ready signal from VlanConfig processing
1106 <-syncChannel
1107 }
1108 if flowsProcessed == len(aPersFlowParam)-1 {
1109 var uniAdded bool
1110 lastFlowToReconcile = true
1111 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1112 apWaitGroup.Add(1) //increment the waiting group
mpagenko101ac942021-11-16 15:01:29 +00001113 }
1114 }
mpagenko101ac942021-11-16 15:01:29 +00001115 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1116 "device-id": dh.DeviceID, "uni-id": loUniID,
1117 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1118 dh.lockVlanConfig.Lock()
1119 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1120 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1121 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301122 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
mpagenko101ac942021-11-16 15:01:29 +00001123 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1124 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1125 }
1126 } else {
1127 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05301128 uint16(flowData.VlanRuleParams.MatchVid), uint8(flowData.VlanRuleParams.MatchPcp), uint16(flowData.VlanRuleParams.SetVid),
mpagenko101ac942021-11-16 15:01:29 +00001129 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1130 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1131 }
1132 }
1133 dh.lockVlanConfig.Unlock()
1134 flowsProcessed++
1135 } //for all flows of this UNI
1136}
1137
1138//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1139// and decrements the according handler wait group waiting for these indications
1140func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1141 waitGroup *cmn.WaitGroupWithTimeOut) {
1142 var reconciledUniVlanConfigEntries []uint8
1143 var appended bool
1144 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1145 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1146 "device-id": dh.DeviceID, "expiry": expiry})
1147 // indicate blocking on channel now to the caller
1148 aSyncChannel <- struct{}{}
1149 for {
1150 select {
1151 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1152 switch uniIndication {
1153 // no activity requested (should normally not be received) - just continue waiting
1154 case cWaitReconcileFlowNoActivity:
1155 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1156 case cWaitReconcileFlowAbortOnError:
1157 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1158 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1159 return
1160 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1161 case cWaitReconcileFlowAbortOnSuccess:
1162 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1163 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1164 return
1165 // this should be a valid UNI vlan config done indication
1166 default:
1167 if uniIndication < platform.MaxUnisPerOnu {
1168 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1169 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1170 if reconciledUniVlanConfigEntries, appended =
1171 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1172 waitGroup.Done()
1173 }
1174 } else {
1175 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1176 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1177 }
1178 } //switch uniIndication
1179
1180 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1181 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1182 log.Fields{"device-id": dh.DeviceID})
1183 return
1184 }
1185 }
1186}
1187
1188func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1189 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1190}
1191
1192func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1193 for _, ele := range slice {
1194 if ele == val {
1195 return slice, false
1196 }
1197 }
1198 return append(slice, val), true
1199}
1200
1201// sendChReconcileFinished - sends true or false on reconcileFinish channel
1202func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1203 if dh != nil { //if the object still exists (might have been already deleted in background)
1204 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1205 select {
1206 case dh.chReconcilingFinished <- success:
1207 default:
1208 }
1209 }
1210}
1211
1212// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1213func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1214 if dh != nil { //if the object still exists (might have been already deleted in background)
1215 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1216 select {
1217 case dh.chUniVlanConfigReconcilingDone <- value:
1218 default:
1219 }
1220 }
1221}
1222
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001224 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001225
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001227 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001228 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001229 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001230 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001231 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001232
1233 // deadline context to ensure completion of background routines waited for
1234 //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 +05301235 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001237
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001239
1240 var wg sync.WaitGroup
1241 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001243 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001244
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001245 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001247}
1248
mpagenko15ff4a52021-03-02 10:09:20 +00001249//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1250// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001252//was and is called in background - error return does not make sense
1253func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001254 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001255 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001257 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001258 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301260 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001261 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001262 return
Himani Chawla4d908332020-08-31 12:30:20 +05301263 }
mpagenko01e726e2020-10-23 09:45:29 +00001264
1265 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001266 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001267
mpagenko44bd8362021-11-15 11:40:05 +00001268 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001270 // 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 -04001271 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001273 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001274 OperStatus: voltha.OperStatus_DISCOVERED,
1275 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001276 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001278 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001279 }
mpagenkoe4782082021-11-25 12:04:26 +00001280 if err := dh.ReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001281 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001282 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001284 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1285 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1286 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1287 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001288}
1289
mpagenkoc8bba412021-01-15 15:38:44 +00001290//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001291// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001292func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001294 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001296
1297 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001298 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001299 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001300 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1301 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001302 }
1303
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001304 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001305 var inactiveImageID uint16
1306 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1307 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001308 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1309 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001310 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001312 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001313 if err == nil {
1314 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1315 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001316 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001317 }
1318 } else {
1319 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001321 }
mpagenko15ff4a52021-03-02 10:09:20 +00001322 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001323 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001325 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1326 dh.upgradeCanceled = true
1327 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1328 }
mpagenko38662d02021-08-11 09:45:19 +00001329 //no effort spent anymore for the old API to automatically cancel and restart the download
1330 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001331 }
mpagenko15ff4a52021-03-02 10:09:20 +00001332 } else {
1333 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001334 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001335 }
1336 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1338 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001339 }
1340 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001341}
1342
mpagenkoc26d4c02021-05-06 14:27:57 +00001343//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1344// after the OnuImage has been downloaded to the adapter, called in background
1345func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001346 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001347
1348 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001350 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001352 return
1353 }
1354
1355 var inactiveImageID uint16
1356 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1357 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001359
mpagenko59862f02021-10-11 08:53:18 +00001360 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001362 // but must be still locked at calling createOnuUpgradeFsm
1363 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1364 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1365 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001366 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1367 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001369 //flush the remove upgradeFsmChan channel
1370 select {
1371 case <-dh.upgradeFsmChan:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001372 logger.Debugw(ctx, "flushed-upgrade-fsm-channel", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001373 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001374 }
mpagenko59862f02021-10-11 08:53:18 +00001375 dh.lockUpgradeFsm.Unlock()
1376 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1377 dh.upgradeCanceled = true
1378 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1379 }
mpagenko38662d02021-08-11 09:45:19 +00001380 select {
1381 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001383 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1384 return
1385 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001387 }
mpagenko59862f02021-10-11 08:53:18 +00001388 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001389 }
mpagenko38662d02021-08-11 09:45:19 +00001390
1391 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001392 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001393 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001394 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001395 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001396 if err == nil {
1397 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1398 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1399 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001401 return
1402 }
mpagenko38662d02021-08-11 09:45:19 +00001403 } else {
1404 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001405 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001406 }
1407 return
1408 }
1409 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001411}
1412
1413//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001414func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1415 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001416 var err error
1417 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1418 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1419 // 2.) activation of the inactive image
1420
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001422 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1424 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001425 }
1426 dh.lockUpgradeFsm.RLock()
1427 if dh.pOnuUpradeFsm != nil {
1428 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001429 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001430 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1432 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001433 }
mpagenko59862f02021-10-11 08:53:18 +00001434 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1435 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1436 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1437 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001438 // use the OnuVendor identification from this device for the internal unique name
1439 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001440 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001441 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001442 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001444 "device-id": dh.DeviceID, "error": err})
1445 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001446 }
mpagenko183647c2021-06-08 15:25:04 +00001447 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001448 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001449 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001450 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001451 } //else
1452 dh.lockUpgradeFsm.RUnlock()
1453
1454 // 2.) check if requested image-version equals the inactive one and start its activation
1455 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1456 var inactiveImageID uint16
1457 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1458 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1460 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001461 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001462 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001463 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001464 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001465 if err == nil {
1466 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1467 inactiveImageID, aCommitRequest); err != nil {
1468 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001469 "device-id": dh.DeviceID, "error": err})
1470 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001471 }
1472 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001474 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001475 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001476 } //else
1477 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001478 "device-id": dh.DeviceID, "error": err})
1479 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001480}
1481
1482//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001483func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1484 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001485 var err error
1486 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1487 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1488 // 2.) commitment of the active image
1489
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001490 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001491 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001492 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1493 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001494 }
1495 dh.lockUpgradeFsm.RLock()
1496 if dh.pOnuUpradeFsm != nil {
1497 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001498 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001499 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1501 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001502 }
mpagenko59862f02021-10-11 08:53:18 +00001503 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1504 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1505 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1506 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001507 // use the OnuVendor identification from this device for the internal unique name
1508 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001509 // 1.) check a started upgrade process and relay the commitment request to it
1510 // the running upgrade may be based either on the imageIdentifier (started from download)
1511 // or on the imageVersion (started from pure activation)
1512 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1513 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001514 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 "device-id": dh.DeviceID, "error": err})
1516 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001517 }
mpagenko183647c2021-06-08 15:25:04 +00001518 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001519 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001520 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001521 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001522 } //else
1523 dh.lockUpgradeFsm.RUnlock()
1524
mpagenko183647c2021-06-08 15:25:04 +00001525 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001526 var activeImageID uint16
1527 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1528 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1530 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001531 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001532 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001534 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001535 if err == nil {
1536 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1537 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001538 "device-id": dh.DeviceID, "error": err})
1539 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001540 }
1541 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001543 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001544 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001545 } //else
1546 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001547 "device-id": dh.DeviceID, "error": err})
1548 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001549}
1550
mpagenkoaa3afe92021-05-21 16:20:58 +00001551func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001552 aVersion string) *voltha.ImageState {
1553 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001554 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001555 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001556 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001557 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1558 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1559 if aVersion == dh.pLastUpgradeImageState.Version {
1560 pImageState = dh.pLastUpgradeImageState
1561 } else { //state request for an image version different from last processed image version
1562 pImageState = &voltha.ImageState{
1563 Version: aVersion,
1564 //we cannot state something concerning this version
1565 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1566 Reason: voltha.ImageState_NO_ERROR,
1567 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1568 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001569 }
1570 }
mpagenko38662d02021-08-11 09:45:19 +00001571 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001572}
1573
1574func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1575 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001576 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001577 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001578 dh.lockUpgradeFsm.RLock()
1579 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001580 dh.lockUpgradeFsm.RUnlock()
1581 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001582 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001583 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1584 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1585 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1586 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1587 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1588 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001589 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1590 dh.upgradeCanceled = true
1591 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1592 }
mpagenko45586762021-10-01 08:30:22 +00001593 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001594 } else {
mpagenko45586762021-10-01 08:30:22 +00001595 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001596 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1597 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1598 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1599 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1600 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1601 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001602 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1603 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001604 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1605 //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 +00001606 }
1607}
1608
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001609func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1610
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001611 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001612
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001614 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1616 pDevEntry.MutexOnuImageStatus.Lock()
1617 pDevEntry.POnuImageStatus = onuImageStatus
1618 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001619
1620 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001621 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001622 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1623 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001624 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1625 pDevEntry.MutexOnuImageStatus.Lock()
1626 pDevEntry.POnuImageStatus = nil
1627 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001628 return images, err
1629}
1630
Himani Chawla6d2ae152020-09-02 13:11:20 +05301631// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001632// #####################################################################################
1633
1634// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301635// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001638 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event),
1639 "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001640}
1641
1642// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001643func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001644
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001645 logger.Debugw(ctx, "doStateInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001646 var err error
1647
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648 // populate what we know. rest comes later after mib sync
1649 dh.device.Root = false
1650 dh.device.Vendor = "OpenONU"
1651 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001652 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
mpagenkoe4782082021-11-25 12:04:26 +00001653 _ = dh.ReasonUpdate(ctx, cmn.DrActivatingOnu, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001654
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001656
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001657 if !dh.IsReconciling() {
1658 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001659 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1660 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1661 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301662 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001664 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001666 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
Himani Chawla4d908332020-08-31 12:30:20 +05301668 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001669 dh.ponPortNumber = dh.device.ParentPortNo
1670
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001671 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1672 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1673 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301676 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001677
1678 /*
1679 self._pon = PonPort.create(self, self._pon_port_number)
1680 self._pon.add_peer(self.parent_id, self._pon_port_number)
1681 self.logger.debug('adding-pon-port-to-agent',
1682 type=self._pon.get_port().type,
1683 admin_state=self._pon.get_port().admin_state,
1684 oper_status=self._pon.get_port().oper_status,
1685 )
1686 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 if !dh.IsReconciling() {
1688 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001689 var ponPortNo uint32 = 1
1690 if dh.ponPortNumber != 0 {
1691 ponPortNo = dh.ponPortNumber
1692 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001694 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001695 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001696 PortNo: ponPortNo,
1697 Label: fmt.Sprintf("pon-%d", ponPortNo),
1698 Type: voltha.Port_PON_ONU,
1699 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301700 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001701 PortNo: ponPortNo}}, // Peer port is parent's port number
1702 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001703 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001704 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001705 e.Cancel(err)
1706 return
1707 }
1708 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001709 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001710 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001711 logger.Debugw(ctx, "doStateInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712}
1713
1714// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001716
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001717 logger.Debugw(ctx, "postInit-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001718 var err error
1719 /*
1720 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1721 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1722 return nil
1723 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001724 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001725 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s:%s", err, dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726 e.Cancel(err)
1727 return
1728 }
1729
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001730 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001732 // reconcilement will be continued after mib download is done
1733 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001734
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735 /*
1736 ############################################################################
1737 # Setup Alarm handler
1738 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1739 device.serial_number)
1740 ############################################################################
1741 # Setup PM configuration for this device
1742 # Pass in ONU specific options
1743 kwargs = {
1744 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1745 'heartbeat': self.heartbeat,
1746 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1747 }
1748 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1749 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1750 self.logical_device_id, device.serial_number,
1751 grouped=True, freq_override=False, **kwargs)
1752 pm_config = self._pm_metrics.make_proto()
1753 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1754 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1755 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1756
1757 # Note, ONU ID and UNI intf set in add_uni_port method
1758 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1759 ani_ports=[self._pon])
1760
1761 # Code to Run OMCI Test Action
1762 kwargs_omci_test_action = {
1763 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1764 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1765 }
1766 serial_number = device.serial_number
1767 self._test_request = OmciTestRequest(self.core_proxy,
1768 self.omci_agent, self.device_id,
1769 AniG, serial_number,
1770 self.logical_device_id,
1771 exclusive=False,
1772 **kwargs_omci_test_action)
1773
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001774 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001775 else:
1776 self.logger.info('onu-already-activated')
1777 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001778
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001779 logger.Debugw(ctx, "postInit-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780}
1781
1782// doStateConnected get the device info and update to voltha core
1783// for comparison of the original method (not that easy to uncomment): compare here:
1784// voltha-openolt-adapter/adaptercore/device_handler.go
1785// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001787
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001788 logger.Debugw(ctx, "doStateConnected-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301789 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001790 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001791 logger.Debugw(ctx, "doStateConnected-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001792}
1793
1794// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001795func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001796
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001797 logger.Debugw(ctx, "doStateUp-started", log.Fields{"device-id": dh.DeviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301798 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001799 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001800 logger.Debugw(ctx, "doStateUp-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001801
1802 /*
1803 // Synchronous call to update device state - this method is run in its own go routine
1804 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1805 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001806 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 +00001807 return err
1808 }
1809 return nil
1810 */
1811}
1812
1813// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001815
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001816 logger.Debugw(ctx, "doStateDown-started", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817 var err error
1818
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001819 device := dh.device
1820 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001821 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001822 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001823 e.Cancel(err)
1824 return
1825 }
1826
1827 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829 /*
1830 // Update the all ports state on that device to disable
1831 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001832 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001833 return er
1834 }
1835
1836 //Update the device oper state and connection status
1837 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1838 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1839 dh.device = cloned
1840
1841 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001842 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001843 return er
1844 }
1845
1846 //get the child device for the parent device
1847 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1848 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001849 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001850 return err
1851 }
1852 for _, onuDevice := range onuDevices.Items {
1853
1854 // Update onu state as down in onu adapter
1855 onuInd := oop.OnuIndication{}
1856 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001857 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001858 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1859 if er != nil {
1860 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001861 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 //Do not return here and continue to process other ONUs
1863 }
1864 }
1865 // * Discovered ONUs entries need to be cleared , since after OLT
1866 // is up, it starts sending discovery indications again* /
1867 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001868 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001869 return nil
1870 */
Himani Chawla4d908332020-08-31 12:30:20 +05301871 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001872 e.Cancel(err)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001873 logger.Debugw(ctx, "doStateDown-done", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001874}
1875
Himani Chawla6d2ae152020-09-02 13:11:20 +05301876// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001877// #################################################################################
1878
1879// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301880// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001882//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1883func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001884 dh.lockDevice.RLock()
1885 pOnuDeviceEntry := dh.pOnuOmciDevice
1886 if aWait && pOnuDeviceEntry == nil {
1887 //keep the read sema short to allow for subsequent write
1888 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001889 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001890 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1891 // so it might be needed to wait here for that event with some timeout
1892 select {
1893 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001894 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001895 return nil
1896 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001897 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001898 // if written now, we can return the written value without sema
1899 return dh.pOnuOmciDevice
1900 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001901 }
mpagenko3af1f032020-06-10 08:53:41 +00001902 dh.lockDevice.RUnlock()
1903 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001904}
1905
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001906//setDeviceHandlerEntries sets the ONU device entry within the handler
1907func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1908 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909 dh.lockDevice.Lock()
1910 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001911 dh.pOnuOmciDevice = apDeviceEntry
1912 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001913 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301914 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001915 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001916}
1917
Himani Chawla6d2ae152020-09-02 13:11:20 +05301918//addOnuDeviceEntry creates a new ONU device or returns the existing
1919func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001920 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001921
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001922 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001923 if deviceEntry == nil {
1924 /* costum_me_map in python code seems always to be None,
1925 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1926 /* also no 'clock' argument - usage open ...*/
1927 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001928 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1929 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1930 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1931 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1932 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001933 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001934 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001935 // fire deviceEntry ready event to spread to possibly waiting processing
1936 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001937 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001939 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001940 }
1941 // might be updated with some error handling !!!
1942 return nil
1943}
1944
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00001946 logger.Debugw(ctx, "create_interface-started", log.Fields{"device-id": dh.DeviceID, "OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001947 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1948
1949 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001952 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1954 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001955 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 if !dh.IsReconciling() {
1957 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001959 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001960 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001962 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001963
khenaidoo42dcdfd2021-10-19 17:34:12 -04001964 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001966 OperStatus: voltha.OperStatus_ACTIVATING,
1967 ConnStatus: voltha.ConnectStatus_REACHABLE,
1968 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001969 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001970 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001971 }
1972 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001975
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001976 pDevEntry.MutexPersOnuConfig.RLock()
1977 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1978 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 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 +00001980 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001981 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001982 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001983 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001984 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001985 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001986 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1987 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1988 // 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 +00001989 // 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 +00001990 // so let's just try to keep it simple ...
1991 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001993 if err != nil || device == nil {
1994 //TODO: needs to handle error scenarios
1995 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1996 return errors.New("Voltha Device not found")
1997 }
1998 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001999
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002000 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002001 return err
mpagenko3af1f032020-06-10 08:53:41 +00002002 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002003 _ = dh.ReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002004
2005 /* this might be a good time for Omci Verify message? */
2006 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002007 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002008 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002009 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002011
2012 /* give the handler some time here to wait for the OMCi verification result
2013 after Timeout start and try MibUpload FSM anyway
2014 (to prevent stopping on just not supported OMCI verification from ONU) */
2015 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002016 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002017 logger.Warnw(ctx, "omci start-verification timed out (continue normal)", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002018 case testresult := <-verifyExec:
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002019 logger.Infow(ctx, "Omci start verification done", log.Fields{"device-id": dh.DeviceID, "result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002020 }
2021
2022 /* In py code it looks earlier (on activate ..)
2023 # Code to Run OMCI Test Action
2024 kwargs_omci_test_action = {
2025 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2026 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2027 }
2028 serial_number = device.serial_number
2029 self._test_request = OmciTestRequest(self.core_proxy,
2030 self.omci_agent, self.device_id,
2031 AniG, serial_number,
2032 self.logical_device_id,
2033 exclusive=False,
2034 **kwargs_omci_test_action)
2035 ...
2036 # Start test requests after a brief pause
2037 if not self._test_request_started:
2038 self._test_request_started = True
2039 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2040 reactor.callLater(tststart, self._test_request.start_collector)
2041
2042 */
2043 /* which is then: in omci_test_request.py : */
2044 /*
2045 def start_collector(self, callback=None):
2046 """
2047 Start the collection loop for an adapter if the frequency > 0
2048
2049 :param callback: (callable) Function to call to collect PM data
2050 """
2051 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2052 if callback is None:
2053 callback = self.perform_test_omci
2054
2055 if self.lc is None:
2056 self.lc = LoopingCall(callback)
2057
2058 if self.default_freq > 0:
2059 self.lc.start(interval=self.default_freq / 10)
2060
2061 def perform_test_omci(self):
2062 """
2063 Perform the initial test request
2064 """
2065 ani_g_entities = self._device.configuration.ani_g_entities
2066 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2067 is not None else None
2068 self._entity_id = ani_g_entities_ids[0]
2069 self.logger.info('perform-test', entity_class=self._entity_class,
2070 entity_id=self._entity_id)
2071 try:
2072 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2073 result = yield self._device.omci_cc.send(frame)
2074 if not result.fields['omci_message'].fields['success_code']:
2075 self.logger.info('Self-Test Submitted Successfully',
2076 code=result.fields[
2077 'omci_message'].fields['success_code'])
2078 else:
2079 raise TestFailure('Test Failure: {}'.format(
2080 result.fields['omci_message'].fields['success_code']))
2081 except TimeoutError as e:
2082 self.deferred.errback(failure.Failure(e))
2083
2084 except Exception as e:
2085 self.logger.exception('perform-test-Error', e=e,
2086 class_id=self._entity_class,
2087 entity_id=self._entity_id)
2088 self.deferred.errback(failure.Failure(e))
2089
2090 */
2091
2092 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002093 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002094
mpagenko1cc3cb42020-07-27 15:24:38 +00002095 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2096 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2097 * 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 +05302098 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002099 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002100 //call MibUploadFSM - transition up to state UlStInSync
2101 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002102 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002103 if pMibUlFsm.Is(mib.UlStDisabled) {
2104 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2105 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2106 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302107 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002108 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302109 //Determine ONU status and start/re-start MIB Synchronization tasks
2110 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002111 if pDevEntry.IsNewOnu() {
2112 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2113 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2114 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002115 }
Himani Chawla4d908332020-08-31 12:30:20 +05302116 } else {
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002117 if err := pMibUlFsm.Event(mib.UlEvVerifyAndStoreTPs); err != nil {
2118 logger.Errorw(ctx, "MibSyncFsm: Can't go to state verify and store TPs", log.Fields{"device-id": dh.DeviceID, "err": err})
2119 return fmt.Errorf("can't go to state verify and store TPs: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302120 }
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002121 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002122 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002123 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002125 "device-id": dh.DeviceID})
2126 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002127 }
2128 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002129 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2130 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002131 }
2132 return nil
2133}
2134
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002136 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002137 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002138 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2139 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002140
mpagenko900ee4b2020-10-12 11:56:34 +00002141 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2142 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2143 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002144 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002146 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002147 // abort: system behavior is just unstable ...
2148 return err
2149 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002150 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 _ = 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 +00002152
2153 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002154 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002155 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002156 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002157 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2158 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002159 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002161
2162 //TODO!!! remove existing traffic profiles
2163 /* from py code, if TP's exist, remove them - not yet implemented
2164 self._tp = dict()
2165 # Let TP download happen again
2166 for uni_id in self._tp_service_specific_task:
2167 self._tp_service_specific_task[uni_id].clear()
2168 for uni_id in self._tech_profile_download_done:
2169 self._tech_profile_download_done[uni_id].clear()
2170 */
2171
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002172 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002173
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002174 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002175
mpagenkoe4782082021-11-25 12:04:26 +00002176 if err := dh.ReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002177 // abort: system behavior is just unstable ...
2178 return err
2179 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002181 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002182 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002183 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002184 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2185 OperStatus: voltha.OperStatus_DISCOVERED,
2186 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002187 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002188 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002189 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002190 // abort: system behavior is just unstable ...
2191 return err
2192 }
2193 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002194 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002195 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002196 return nil
2197}
2198
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002199func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002200 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2201 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2202 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2203 // and using the stop/reset event should never harm
2204
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002205 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002206 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2208 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002209 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002210 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002211 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002212 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 pDevEntry.MutexOnuImageStatus.RLock()
2214 if pDevEntry.POnuImageStatus != nil {
2215 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002216 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002217 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002218
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002219 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002220 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002221 }
2222 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002223 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002224 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002226 }
mpagenko101ac942021-11-16 15:01:29 +00002227 //stop any deviceHandler reconcile processing (if running)
2228 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002229 //port lock/unlock FSM's may be active
2230 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002232 }
2233 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002234 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002235 }
2236 //techProfile related PonAniConfigFsm FSM may be active
2237 if dh.pOnuTP != nil {
2238 // should always be the case here
2239 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002240 if dh.pOnuTP.PAniConfigFsm != nil {
2241 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2242 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002243 }
mpagenko900ee4b2020-10-12 11:56:34 +00002244 }
2245 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002246 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002247 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002249 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002250 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002251 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002252 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002253 } else {
2254 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002255 }
2256 }
2257 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002258 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002259 // Stop collector routine
2260 dh.stopCollector <- true
2261 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302263 dh.stopAlarmManager <- true
2264 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002265 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002266 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002267 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302268
Girish Gowdrae95687a2021-09-08 16:30:58 -07002269 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2270
mpagenko80622a52021-02-09 16:53:23 +00002271 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002272 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002273 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002274 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002276 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002277 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002278 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2279 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2280 // (even though it may also run into direct cancellation, a bit hard to verify here)
2281 // so don't set 'dh.upgradeCanceled = true' here!
2282 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2283 }
mpagenko38662d02021-08-11 09:45:19 +00002284 }
mpagenko80622a52021-02-09 16:53:23 +00002285
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002286 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002287 return nil
2288}
2289
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002290func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2291 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 +05302292
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002293 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002295 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002297 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002298 _ = dh.ReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002300
mpagenkoa40e99a2020-11-17 13:50:39 +00002301 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2302 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2303 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2304 * disable/enable toggling here to allow traffic
2305 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2306 * like the py comment says:
2307 * # start by locking all the unis till mib sync and initial mib is downloaded
2308 * # this way we can capture the port down/up events when we are ready
2309 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302310
mpagenkoa40e99a2020-11-17 13:50:39 +00002311 // Init Uni Ports to Admin locked state
2312 // *** should generate UniLockStateDone event *****
2313 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002315 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002318 }
2319}
2320
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2322 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302323 /* Mib download procedure -
2324 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2325 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002327 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002329 return
2330 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002331 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302332 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 if pMibDlFsm.Is(mib.DlStDisabled) {
2334 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2335 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 +05302336 // maybe try a FSM reset and then again ... - TODO!!!
2337 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002338 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302339 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002340 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2341 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302342 } else {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002343 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"device-id": dh.DeviceID, "state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302344 //Begin MIB data download (running autonomously)
2345 }
2346 }
2347 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002348 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302350 // maybe try a FSM reset and then again ... - TODO!!!
2351 }
2352 /***** Mib download started */
2353 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302355 }
2356}
2357
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002358func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2359 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302360 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002361 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002362 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002364 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2365 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2366 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2367 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002368 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002369 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002370 ConnStatus: voltha.ConnectStatus_REACHABLE,
2371 OperStatus: voltha.OperStatus_ACTIVE,
2372 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302373 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002374 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 }
2378 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002380 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302381 }
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002382 _ = dh.ReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002383
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002385 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002387 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 if !dh.GetAlarmManagerIsRunning(ctx) {
2389 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002390 }
2391
Girish Gowdrae95687a2021-09-08 16:30:58 -07002392 // Start flow handler routines per UNI
2393 for _, uniPort := range dh.uniEntityMap {
2394 // only if this port was enabled for use by the operator at startup
2395 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2396 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2397 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2398 }
2399 }
2400 }
2401
Girish Gowdrae0140f02021-02-02 16:55:09 -08002402 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002404 // There is no way we should be landing here, but if we do then
2405 // there is nothing much we can do about this other than log error
2406 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2407 }
2408
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002409 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002410
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002412 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002413 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002414 return
2415 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002416 pDevEntry.MutexPersOnuConfig.RLock()
2417 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2418 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002419 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 log.Fields{"device-id": dh.DeviceID})
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002421 dh.mutexForDisableDeviceRequested.Lock()
2422 dh.disableDeviceRequested = true
2423 dh.mutexForDisableDeviceRequested.Unlock()
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002424 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002425 // reconcilement will be continued after ani config is done
2426 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002427 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002428 // *** should generate UniUnlockStateDone event *****
ozgecanetsia5cbcfbe2022-01-14 10:32:34 +03002429 dh.mutexForDisableDeviceRequested.RLock()
2430 if !dh.disableDeviceRequested {
2431 if dh.pUnlockStateFsm == nil {
2432 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
2433 } else { //UnlockStateFSM already init
2434 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
2435 dh.runUniLockFsm(ctx, false)
2436 }
2437 dh.mutexForDisableDeviceRequested.RUnlock()
2438 } else {
2439 dh.mutexForDisableDeviceRequested.RUnlock()
2440 logger.Debugw(ctx, "Uni already lock", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002441 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302442 }
2443}
2444
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002445func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2446 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302447
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002448 if !dh.IsReconciling() {
2449 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002450 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002451 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2452 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002453 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002455 return
2456 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002457 pDevEntry.MutexPersOnuConfig.Lock()
2458 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2459 pDevEntry.MutexPersOnuConfig.Unlock()
2460 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002461 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002463 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302464 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 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 +00002466 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002467 dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002468 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302469 }
2470}
2471
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002473 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002474 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002475
mpagenko44bd8362021-11-15 11:40:05 +00002476 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002477 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002479 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002480 OperStatus: voltha.OperStatus_UNKNOWN,
2481 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002482 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002484 }
2485
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002486 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002487 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002488 _ = dh.ReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002489
2490 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002491 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002492
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002494 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002496 return
2497 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498 pDevEntry.MutexPersOnuConfig.Lock()
2499 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2500 pDevEntry.MutexPersOnuConfig.Unlock()
2501 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002504 }
mpagenko900ee4b2020-10-12 11:56:34 +00002505}
2506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002507func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002510 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002511 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002512 ConnStatus: voltha.ConnectStatus_REACHABLE,
2513 OperStatus: voltha.OperStatus_ACTIVE,
2514 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002515 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002516 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002517 }
2518
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002520 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002521 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
mpagenkoe4782082021-11-25 12:04:26 +00002522 _ = dh.ReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002523
2524 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002526
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002527 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002528 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002529 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002530 return
2531 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 pDevEntry.MutexPersOnuConfig.Lock()
2533 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2534 pDevEntry.MutexPersOnuConfig.Unlock()
2535 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002538 }
mpagenko900ee4b2020-10-12 11:56:34 +00002539}
2540
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002541func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2542 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2543 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002544 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002545 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002546 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002547 OperStatus: voltha.OperStatus_FAILED,
2548 }); err != nil {
2549 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2550 }
2551}
2552
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002553func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2554 if devEvent == cmn.OmciAniConfigDone {
2555 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002556 // attention: the device reason update is done based on ONU-UNI-Port related activity
2557 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002559 // 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 +00002560 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
Himani Chawla26e555c2020-08-31 12:30:20 +05302561 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002562 if dh.IsReconciling() {
Holger Hildebrandt7741f272022-01-18 08:17:39 +00002563 // during reconciling with OMCI configuration in TT multi-UNI scenario, OmciAniConfigDone is reached several times
2564 // therefore it must be ensured that reconciling of flow config is only started on the first pass of this code position
2565 dh.mutexReconcilingFirstPassFlag.Lock()
2566 if dh.reconcilingFirstPass {
2567 logger.Debugw(ctx, "reconciling - OmciAniConfigDone first pass, start flow processing", log.Fields{"device-id": dh.DeviceID})
2568 dh.reconcilingFirstPass = false
2569 go dh.ReconcileDeviceFlowConfig(ctx)
2570 }
2571 dh.mutexReconcilingFirstPassFlag.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00002572 }
2573 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002575 // attention: the device reason update is done based on ONU-UNI-Port related activity
2576 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002577 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkoe4782082021-11-25 12:04:26 +00002578 // which may be the case from some previous activity even on this ONU port (but also other UNI ports)
2579 _ = dh.ReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002580 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002581 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302582}
2583
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002585 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002586 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302587 // attention: the device reason update is done based on ONU-UNI-Port related activity
2588 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2591 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkoe4782082021-11-25 12:04:26 +00002592 // which may be the case from some previous activity on another UNI Port of the ONU
mpagenkofc4f56e2020-11-04 17:17:49 +00002593 // or even some previous flow add activity on the same port
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00002594 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling() || dh.IsReconcilingReasonUpdate())
mpagenkofc4f56e2020-11-04 17:17:49 +00002595 }
2596 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002598 //not relevant for reconcile
mpagenkoe4782082021-11-25 12:04:26 +00002599 _ = dh.ReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002600 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302601 }
mpagenkof1fc3862021-02-16 10:09:52 +00002602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002604 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002606 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002608 }
2609 } else {
2610 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002612 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302613}
2614
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002615//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2616func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302617 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002618 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002619 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002620 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002621 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002622 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002623 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002625 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002626 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002627 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002628 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002629 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002631 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002633 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002635 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002636 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002637 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002638 case cmn.UniEnableStateFailed:
2639 {
2640 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2641 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002642 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002643 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002644 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002645 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002647 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002648 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002649 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002650 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002651 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002652 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002653 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002654 default:
2655 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002657 }
2658 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002659}
2660
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002661func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002662 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002663 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302664 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002665 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002666 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"device-id": dh.DeviceID, "for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002667 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302668 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002669 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002670 if pUniPort == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002671 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 +00002672 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002673 //store UniPort with the System-PortNumber key
2674 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002676 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002678 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"device-id": dh.DeviceID, "for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002679 } //error logging already within UniPort method
2680 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002681 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002682 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002683 }
2684 }
2685}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002686
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2688 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002689 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002691 return
2692 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002693 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002695 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2696 for _, mgmtEntityID := range pptpInstKeys {
2697 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002699 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2700 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002701 }
2702 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002704 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002706 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2707 for _, mgmtEntityID := range veipInstKeys {
2708 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002710 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2711 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002712 }
2713 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002714 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002715 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002716 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002717 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2718 for _, mgmtEntityID := range potsInstKeys {
2719 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002721 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2722 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002723 }
2724 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002726 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002727 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002729 return
2730 }
2731
mpagenko2c3f6c52021-11-23 11:22:10 +00002732 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2733 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2734 // 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 -07002735 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2736 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2737 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002738 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2739 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002740 for i := 0; i < int(uniCnt); i++ {
2741 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2742 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002743 }
2744}
2745
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2747func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002748 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302749 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002750 // with following remark:
2751 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2752 // # load on the core
2753
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002754 // 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 +00002755
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002756 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002757 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2759 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2760 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2761 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002762 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002763 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002764 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002766 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 PortNo: port.PortNo,
2768 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002769 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 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 -04002771 }
2772 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002773 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002775 }
mpagenko3af1f032020-06-10 08:53:41 +00002776 }
2777 }
2778}
2779
2780// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2782 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002783 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2784 for uniNo, uniPort := range dh.uniEntityMap {
2785 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002786
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2788 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2789 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2790 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002791 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002792 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002793 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002795 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002796 PortNo: port.PortNo,
2797 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002798 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002799 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 -04002800 }
2801 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002802 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002804 }
2805
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002806 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002807 }
2808}
2809
2810// ONU_Active/Inactive announcement on system KAFKA bus
2811// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002812func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002813 var de voltha.DeviceEvent
2814 eventContext := make(map[string]string)
2815 //Populating event context
2816 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002817 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002818 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002820 log.Fields{"device-id": dh.DeviceID, "parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002821 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 +00002822 }
2823 oltSerialNumber := parentDevice.SerialNumber
2824
2825 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2826 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2827 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302828 eventContext["olt-serial-number"] = oltSerialNumber
2829 eventContext["device-id"] = aDeviceID
2830 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002831 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2833 deviceEntry.MutexPersOnuConfig.RLock()
2834 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2835 deviceEntry.MutexPersOnuConfig.RUnlock()
2836 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2837 deviceEntry.MutexPersOnuConfig.RLock()
2838 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2839 deviceEntry.MutexPersOnuConfig.RUnlock()
2840 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002841 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2842 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2843 } else {
2844 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2845 log.Fields{"device-id": aDeviceID})
2846 return
2847 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002848
2849 /* Populating device event body */
2850 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302851 de.ResourceId = aDeviceID
2852 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002853 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2854 de.Description = fmt.Sprintf("%s Event - %s - %s",
2855 cEventObjectType, cOnuActivatedEvent, "Raised")
2856 } else {
2857 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2858 de.Description = fmt.Sprintf("%s Event - %s - %s",
2859 cEventObjectType, cOnuActivatedEvent, "Cleared")
2860 }
2861 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2863 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302864 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002865 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302867 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002868}
2869
Himani Chawla4d908332020-08-31 12:30:20 +05302870// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2872 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002873 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302874 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002875 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002876 sFsmName = "LockStateFSM"
2877 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002878 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002879 sFsmName = "UnLockStateFSM"
2880 }
mpagenko3af1f032020-06-10 08:53:41 +00002881
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002883 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002885 return
2886 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002887 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002888 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302889 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002890 dh.pLockStateFsm = pLSFsm
2891 } else {
2892 dh.pUnlockStateFsm = pLSFsm
2893 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002895 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002896 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002897 }
2898}
2899
2900// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002901func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002902 /* Uni Port lock/unlock procedure -
2903 ***** should run via 'adminDone' state and generate the argument requested event *****
2904 */
2905 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302906 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002907 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002908 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2909 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2911 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002912 }
2913 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002915 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2916 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002917 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2918 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002919 }
2920 }
2921 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2923 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002924 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002925 // maybe try a FSM reset and then again ... - TODO!!!
2926 } else {
2927 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002928 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002930 }
2931 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002932 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002933 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002934 // maybe try a FSM reset and then again ... - TODO!!!
2935 }
2936 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002938 // maybe try a FSM reset and then again ... - TODO!!!
2939 }
2940}
2941
mpagenko80622a52021-02-09 16:53:23 +00002942// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002943// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002946 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002948 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002950 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002951 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002953 sFsmName, chUpgradeFsm)
2954 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002955 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002956 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2958 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00002959 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko80622a52021-02-09 16:53:23 +00002960 // maybe try a FSM reset and then again ... - TODO!!!
2961 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2962 }
mpagenko59862f02021-10-11 08:53:18 +00002963 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002964 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2965 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002966 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2967 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002968 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002970 } else {
2971 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002973 // maybe try a FSM reset and then again ... - TODO!!!
2974 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2975 }
2976 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002978 // maybe try a FSM reset and then again ... - TODO!!!
2979 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2980 }
2981 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002982 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002983 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2984 }
2985 return nil
2986}
2987
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002988// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2989func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002990 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002992 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002993 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2994 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002995 dh.pLastUpgradeImageState = apImageState
2996 dh.lockUpgradeFsm.Unlock()
2997 //signal upgradeFsm removed using non-blocking channel send
2998 select {
2999 case dh.upgradeFsmChan <- struct{}{}:
3000 default:
3001 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003002 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00003003 }
mpagenko80622a52021-02-09 16:53:23 +00003004}
3005
mpagenko15ff4a52021-03-02 10:09:20 +00003006// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
3007func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00003009 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003010 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003011 return
3012 }
3013
3014 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003015 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003016 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003017 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3018 dh.lockUpgradeFsm.RUnlock()
3019 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3020 return
3021 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003023 if pUpgradeStatemachine != nil {
3024 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3025 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003026 UpgradeState := pUpgradeStatemachine.Current()
3027 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3028 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3029 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003030 // 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 +00003031 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003032 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3033 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003034 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003035 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003037 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3038 dh.upgradeCanceled = true
3039 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3040 }
mpagenko15ff4a52021-03-02 10:09:20 +00003041 return
3042 }
mpagenko59862f02021-10-11 08:53:18 +00003043 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003044 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3045 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003046 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003048 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event",
3049 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003050 return
3051 }
3052 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003053 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003054 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003055 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3056 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003057 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event",
3058 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenko1f8e8822021-06-25 14:10:21 +00003059 return
3060 }
3061 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003063 }
3064 } else {
3065 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 +00003066 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003067 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3068 dh.upgradeCanceled = true
3069 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3070 }
mpagenko1f8e8822021-06-25 14:10:21 +00003071 }
mpagenko15ff4a52021-03-02 10:09:20 +00003072 return
3073 }
mpagenko59862f02021-10-11 08:53:18 +00003074 dh.lockUpgradeFsm.RUnlock()
3075 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3076 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003077 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3078 dh.upgradeCanceled = true
3079 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3080 }
mpagenko59862f02021-10-11 08:53:18 +00003081 return
3082 }
3083 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3084 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3085 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3086 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3087 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3088 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3089 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003090 }
mpagenko15ff4a52021-03-02 10:09:20 +00003091 }
3092 }
3093 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003095 }
mpagenko59862f02021-10-11 08:53:18 +00003096 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003097}
3098
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099//SetBackend provides a DB backend for the specified path on the existing KV client
3100func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003101
3102 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003103 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003104 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003105 kvbackend := &db.Backend{
3106 Client: dh.pOpenOnuAc.kvClient,
3107 StoreType: dh.pOpenOnuAc.KVStoreType,
3108 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003109 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003110 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3111 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003112
mpagenkoaf801632020-07-03 10:00:42 +00003113 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003114}
khenaidoo7d3c5582021-08-11 18:09:44 -04003115func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303116 loMatchPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003117
mpagenkodff5dda2020-08-28 11:52:01 +00003118 for _, field := range flow.GetOfbFields(apFlowItem) {
3119 switch field.Type {
3120 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3121 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003123 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3124 }
mpagenko01e726e2020-10-23 09:45:29 +00003125 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003126 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3127 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303128 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003129 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303130 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3131 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003132 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3133 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003134 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003135 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303136 return
mpagenkodff5dda2020-08-28 11:52:01 +00003137 }
3138 }
mpagenko01e726e2020-10-23 09:45:29 +00003139 */
mpagenkodff5dda2020-08-28 11:52:01 +00003140 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3141 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303142 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003143 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303144 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003145 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303146 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003147 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303149 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003150 }
3151 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3152 {
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303153 *loMatchPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003154 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303155 "PCP": loMatchPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003156 }
3157 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3158 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003159 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003160 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3161 }
3162 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3163 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003164 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003165 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3166 }
3167 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3168 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003169 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003170 "IPv4-DST": field.GetIpv4Dst()})
3171 }
3172 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
3173 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003175 "IPv4-SRC": field.GetIpv4Src()})
3176 }
3177 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
3178 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003180 "Metadata": field.GetTableMetadata()})
3181 }
3182 /*
3183 default:
3184 {
3185 //all other entires ignored
3186 }
3187 */
3188 }
3189 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303190}
mpagenkodff5dda2020-08-28 11:52:01 +00003191
khenaidoo7d3c5582021-08-11 18:09:44 -04003192func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003193 for _, action := range flow.GetActions(apFlowItem) {
3194 switch action.Type {
3195 /* not used:
3196 case of.OfpActionType_OFPAT_OUTPUT:
3197 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003198 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003199 "Output": action.GetOutput()})
3200 }
3201 */
3202 case of.OfpActionType_OFPAT_PUSH_VLAN:
3203 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003204 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003205 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3206 }
3207 case of.OfpActionType_OFPAT_SET_FIELD:
3208 {
3209 pActionSetField := action.GetSetField()
3210 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003211 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003212 "OxcmClass": pActionSetField.Field.OxmClass})
3213 }
3214 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303215 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003216 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303217 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003218 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303219 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003220 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303221 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003222 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003224 "Type": pActionSetField.Field.GetOfbField().Type})
3225 }
3226 }
3227 /*
3228 default:
3229 {
3230 //all other entires ignored
3231 }
3232 */
3233 }
3234 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303235}
3236
3237//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003238func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003239 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303240 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3241 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303242 var loSetPcp uint8
3243 var loMatchPcp uint8 = 8 // could the const 'cPrioDoNotFilter' be used from omci_vlan_config.go ?
Himani Chawla26e555c2020-08-31 12:30:20 +05303244 var loIPProto uint32
3245 /* the TechProfileId is part of the flow Metadata - compare also comment within
3246 * OLT-Adapter:openolt_flowmgr.go
3247 * Metadata 8 bytes:
3248 * Most Significant 2 Bytes = Inner VLAN
3249 * Next 2 Bytes = Tech Profile ID(TPID)
3250 * Least Significant 4 Bytes = Port ID
3251 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3252 * subscriber related flows.
3253 */
3254
dbainbri4d3a0dc2020-12-02 00:33:42 +00003255 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303256 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003257 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003258 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003259 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303260 }
mpagenko551a4d42020-12-08 18:09:20 +00003261 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003262 loCookie := apFlowItem.GetCookie()
3263 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003264 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003265 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303266
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303267 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loMatchPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003268 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303269 if loIPProto == 2 {
3270 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3271 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003272 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303274 return nil
3275 }
mpagenko01e726e2020-10-23 09:45:29 +00003276 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003277 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003278
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303279 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) && (loMatchPcp == 8) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003280 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003281 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003282 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3283 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3284 //TODO!!: Use DeviceId within the error response to rwCore
3285 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003286 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003287 }
3288 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003289 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003290 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3291 } else {
3292 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3293 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3294 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303295 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003296 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003297 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003298 }
mpagenko9a304ea2020-12-16 15:54:01 +00003299
khenaidoo42dcdfd2021-10-19 17:34:12 -04003300 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003301 if apFlowMetaData != nil {
3302 meter = apFlowMetaData.Meters[0]
3303 }
mpagenkobc4170a2021-08-17 16:42:10 +00003304 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3305 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3306 // when different rules are requested concurrently for the same uni
3307 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3308 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3309 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003310 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3311 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003312 //SetUniFlowParams() may block on some rule that is suspended-to-add
3313 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003314 // Also the error is returned to caller via response channel
3315 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303316 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003317 dh.lockVlanConfig.RUnlock()
3318 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003319 return
mpagenkodff5dda2020-08-28 11:52:01 +00003320 }
mpagenkobc4170a2021-08-17 16:42:10 +00003321 dh.lockVlanConfig.RUnlock()
3322 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003323 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303324 loMatchVlan, loMatchPcp, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003325 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003326 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003327 if err != nil {
3328 *respChan <- err
3329 }
mpagenko01e726e2020-10-23 09:45:29 +00003330}
3331
3332//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003333func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003334 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3335 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3336 //no extra check is done on the rule parameters
3337 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3338 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3339 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3340 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003341 // - 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 +00003342 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003343 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003344
3345 /* TT related temporary workaround - should not be needed anymore
3346 for _, field := range flow.GetOfbFields(apFlowItem) {
3347 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3348 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003350 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3351 if loIPProto == 2 {
3352 // 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 +00003353 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003354 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003355 return nil
3356 }
3357 }
3358 } //for all OfbFields
3359 */
3360
mpagenko9a304ea2020-12-16 15:54:01 +00003361 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003362 dh.lockVlanConfig.RLock()
3363 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003364 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3365 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003366 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3367 return
mpagenko01e726e2020-10-23 09:45:29 +00003368 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003369 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003370 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003371 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003372 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003373 // Push response on the response channel
3374 if respChan != nil {
3375 // 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
3376 select {
3377 case *respChan <- nil:
3378 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3379 default:
3380 }
3381 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003382 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003383}
3384
Himani Chawla26e555c2020-08-31 12:30:20 +05303385// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003386// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003387// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303389 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003390 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003391
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003392 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003393 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3395 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003396 }
3397
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3399 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +05303400 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003401 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003402 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3403 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003404 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3405 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003406 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3408 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003409 logger.Warnw(ctx, "UniVlanConfigFsm: can't start",
3410 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003411 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003412 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303413 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003414 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003415 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3416 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003417 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003418 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003419 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3420 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003421 }
3422 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003423 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003424 "device-id": dh.DeviceID})
3425 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003426 }
3427 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003428 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3430 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003431 }
3432 return nil
3433}
3434
mpagenkofc4f56e2020-11-04 17:17:49 +00003435//VerifyVlanConfigRequest checks on existence of a given uniPort
3436// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003437func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003438 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003439 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003440 for _, uniPort := range dh.uniEntityMap {
3441 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003443 pCurrentUniPort = uniPort
3444 break //found - end search loop
3445 }
3446 }
3447 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003448 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003449 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003450 return
3451 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003453}
3454
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3456func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003457 //TODO!! verify and start pending flow configuration
3458 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3459 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003460
3461 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003462 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003463 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003464 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003466 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003467 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003468 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3470 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003471 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003472 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003473 } else {
3474 /***** UniVlanConfigFsm continued */
3475 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003476 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3477 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003478 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003479 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3480 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003481 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003482 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003483 } else {
3484 /***** UniVlanConfigFsm continued */
3485 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003486 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3487 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003488 }
mpagenkodff5dda2020-08-28 11:52:01 +00003489 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003490 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003491 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3492 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003493 }
3494 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003495 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 +00003496 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3497 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003498 }
3499 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003500 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003501 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003502 }
mpagenkof1fc3862021-02-16 10:09:52 +00003503 } else {
3504 dh.lockVlanConfig.RUnlock()
3505 }
mpagenkodff5dda2020-08-28 11:52:01 +00003506}
3507
3508//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3509// 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 +00003510func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003511 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003513 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003514 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003515 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003516 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003517}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003518
mpagenkof1fc3862021-02-16 10:09:52 +00003519//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003520func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003521 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3522 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3523 // obviously then parallel processing on the cancel must be avoided
3524 // deadline context to ensure completion of background routines waited for
3525 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3526 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3527 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3528
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003529 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003530 var wg sync.WaitGroup
3531 wg.Add(1) // for the 1 go routine to finish
3532
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003534 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3535
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003536 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003537}
3538
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003539//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003540//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3542 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003543
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003544 if dh.IsReconciling() {
3545 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003546 return nil
3547 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003549
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003551 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003552 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3553 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003554 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003556
mpagenkof1fc3862021-02-16 10:09:52 +00003557 if aWriteToKvStore {
3558 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3559 }
3560 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003561}
3562
dbainbri4d3a0dc2020-12-02 00:33:42 +00003563func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003564 defer cancel() //ensure termination of context (may be pro forma)
3565 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003566 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003567 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003568}
3569
mpagenkoe4782082021-11-25 12:04:26 +00003570//ReasonUpdate set the internally store device reason and if requested in notifyCore updates this state in the core
3571// (renamed from previous deviceReasonUpdate to avoid confusing with the core function DeviceReasonUpdate)
3572func (dh *deviceHandler) ReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
3573 // acquire the deviceReason semaphore throughout this function including the possible update processing in core
3574 // in order to avoid reversion of the state sequence within core in case of quasi-parallel calls (eg. in multi UNI processing)
3575 dh.mutexDeviceReason.Lock()
3576 defer dh.mutexDeviceReason.Unlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003577 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003578 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003579 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003580 DeviceId: dh.DeviceID,
3581 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003582 }); err != nil {
mpagenkoe4782082021-11-25 12:04:26 +00003583 logger.Errorf(ctx, "updating reason in core failed for: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003584 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003585 return err
3586 }
mpagenkoe4782082021-11-25 12:04:26 +00003587 } else {
3588 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 +00003589 }
mpagenkoe4782082021-11-25 12:04:26 +00003590 dh.deviceReason = deviceReason
3591 logger.Infof(ctx, "reason update done for: %s - device-id: %s - with core update: %v",
3592 cmn.DeviceReasonMap[deviceReason], dh.DeviceID, notifyCore)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003593 return nil
3594}
3595
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003596func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3597 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003598 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003599 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3600 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003601 }
mpagenkof1fc3862021-02-16 10:09:52 +00003602 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003603}
3604
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003605// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003606// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003607func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3608 dh.lockDevice.RLock()
3609 defer dh.lockDevice.RUnlock()
3610 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003611 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003612 }
3613 return 0, errors.New("error-fetching-uni-port")
3614}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003615
3616// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003617func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3618 var errorsList []error
3619 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 -08003620
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003621 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3622 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3623 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3624
3625 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3626 // successfully.
3627 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3628 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3629 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003630 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 -08003631 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003633 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003634 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003635}
3636
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003637func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3638 var err error
3639 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003640 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003641
3642 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003643 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003644 errorsList = append(errorsList, err)
3645 }
3646 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003647 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003648
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003649 return errorsList
3650}
3651
3652func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3653 var err error
3654 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003655 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003656 // Check if group metric related config is updated
3657 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3659 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3660 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003661
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 if ok && m.Frequency != v.GroupFreq {
3663 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003664 errorsList = append(errorsList, err)
3665 }
3666 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003667 if ok && m.Enabled != v.Enabled {
3668 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003669 errorsList = append(errorsList, err)
3670 }
3671 }
3672 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003673 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003674 return errorsList
3675}
3676
3677func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3678 var err error
3679 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003680 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003681 // Check if standalone metric related config is updated
3682 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003683 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3684 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3685 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003686
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003687 if ok && m.Frequency != v.SampleFreq {
3688 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003689 errorsList = append(errorsList, err)
3690 }
3691 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003692 if ok && m.Enabled != v.Enabled {
3693 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003694 errorsList = append(errorsList, err)
3695 }
3696 }
3697 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003698 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003699 return errorsList
3700}
3701
3702// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003703func (dh *deviceHandler) StartCollector(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003704 logger.Debugw(ctx, "startingCollector", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae09a6202021-01-12 18:10:59 -08003705
3706 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003707 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303708 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003709 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003710 // Initialize the next metric collection time.
3711 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3712 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003713 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003714 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003715 for {
3716 select {
3717 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003718 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003719 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003720 // Stop the L2 PM FSM
3721 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003722 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3723 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3724 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003725 }
3726 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003727 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003728 }
3729 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003730 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3731 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003732 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003733 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3734 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003735 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003736
Girish Gowdrae09a6202021-01-12 18:10:59 -08003737 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003738 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3739 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3740 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3741 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3742 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003743 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003744 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003745 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003746 } else {
3747 if dh.pmConfigs.Grouped { // metrics are managed as a group
3748 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003749 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003750
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003751 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3752 // 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 -08003753 // 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 +00003754 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3755 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003756 }
3757 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003758 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3759 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3760 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3761 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003762 }
3763 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003764 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003765
3766 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003767 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3768 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3769 // 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 -08003770 // 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 +00003771 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3772 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003773 }
3774 }
3775 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003776 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3777 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3778 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3779 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003780 }
3781 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003782 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003783 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003784 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003785 } */
3786 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003787 }
3788 }
3789}
kesavandfdf77632021-01-26 23:40:33 -05003790
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003792
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003793 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3794 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003795}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003796
Himani Chawla43f95ff2021-06-03 00:24:12 +05303797func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3798 if dh.pOnuMetricsMgr == nil {
3799 return &extension.SingleGetValueResponse{
3800 Response: &extension.GetValueResponse{
3801 Status: extension.GetValueResponse_ERROR,
3802 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3803 },
3804 }
3805 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303806 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303807 return resp
3808}
3809
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003810func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3811 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003812 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003813 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003814 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003815}
3816
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003817func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003818 var pAdapterFsm *cmn.AdapterFsm
3819 //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 +00003820 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003821 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003822 {
mpagenkofbf577d2021-10-12 11:44:33 +00003823 if dh.pOnuOmciDevice != nil {
3824 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3825 } else {
3826 return true //FSM not active - so there is no activity on omci
3827 }
mpagenkof1fc3862021-02-16 10:09:52 +00003828 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003829 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003830 {
mpagenkofbf577d2021-10-12 11:44:33 +00003831 if dh.pOnuOmciDevice != nil {
3832 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3833 } else {
3834 return true //FSM not active - so there is no activity on omci
3835 }
mpagenkof1fc3862021-02-16 10:09:52 +00003836 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003837 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003838 {
mpagenkofbf577d2021-10-12 11:44:33 +00003839 if dh.pLockStateFsm != nil {
3840 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3841 } else {
3842 return true //FSM not active - so there is no activity on omci
3843 }
mpagenkof1fc3862021-02-16 10:09:52 +00003844 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003845 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003846 {
mpagenkofbf577d2021-10-12 11:44:33 +00003847 if dh.pUnlockStateFsm != nil {
3848 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3849 } else {
3850 return true //FSM not active - so there is no activity on omci
3851 }
mpagenkof1fc3862021-02-16 10:09:52 +00003852 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003853 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003854 {
mpagenkofbf577d2021-10-12 11:44:33 +00003855 if dh.pOnuMetricsMgr != nil {
3856 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003857 } else {
3858 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003859 }
3860 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003861 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003862 {
3863 dh.lockUpgradeFsm.RLock()
3864 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003865 if dh.pOnuUpradeFsm != nil {
3866 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3867 } else {
3868 return true //FSM not active - so there is no activity on omci
3869 }
mpagenko80622a52021-02-09 16:53:23 +00003870 }
mpagenkof1fc3862021-02-16 10:09:52 +00003871 default:
3872 {
3873 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003875 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003876 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003877 }
mpagenkofbf577d2021-10-12 11:44:33 +00003878 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3879 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3880 }
3881 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003882}
3883
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003884func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3885 for _, v := range dh.pOnuTP.PAniConfigFsm {
3886 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003887 return false
3888 }
3889 }
3890 return true
3891}
3892
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003893func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003894 dh.lockVlanConfig.RLock()
3895 defer dh.lockVlanConfig.RUnlock()
3896 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003897 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003898 return false
3899 }
3900 }
3901 return true //FSM not active - so there is no activity on omci
3902}
3903
3904func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3905 dh.lockVlanConfig.RLock()
3906 defer dh.lockVlanConfig.RUnlock()
3907 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 if v.PAdaptFsm.PFsm != nil {
3909 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003910 return true //there is at least one VLAN FSM with some active configuration
3911 }
3912 }
3913 }
3914 return false //there is no VLAN FSM with some active configuration
3915}
3916
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003917func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003918 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3919 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3920 return false
3921 }
3922 }
3923 // a further check is done to identify, if at least some data traffic related configuration exists
3924 // 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])
3925 return dh.checkUserServiceExists(ctx)
3926}
3927
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003928func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003929 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3930 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003931 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003932 // TODO: fatal error reset ONU, delete deviceHandler!
3933 return
3934 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003935 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3936 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003937}
3938
3939func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3940 dh.mutexCollectorFlag.Lock()
3941 dh.collectorIsRunning = flagValue
3942 dh.mutexCollectorFlag.Unlock()
3943}
3944
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003945func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003946 dh.mutexCollectorFlag.RLock()
3947 flagValue := dh.collectorIsRunning
3948 dh.mutexCollectorFlag.RUnlock()
3949 return flagValue
3950}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303951
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303952func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3953 dh.mutextAlarmManagerFlag.Lock()
3954 dh.alarmManagerIsRunning = flagValue
3955 dh.mutextAlarmManagerFlag.Unlock()
3956}
3957
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003958func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303959 dh.mutextAlarmManagerFlag.RLock()
3960 flagValue := dh.alarmManagerIsRunning
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003961 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"device-id": dh.device.Id, "flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303962 dh.mutextAlarmManagerFlag.RUnlock()
3963 return flagValue
3964}
3965
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003966func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003967 logger.Debugw(ctx, "startingAlarmManager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303968
3969 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003970 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303971 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303972 if stop := <-dh.stopAlarmManager; stop {
3973 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303974 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303975 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003976 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3977 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303978 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303979 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003980 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3981 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303982 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303983 }
3984}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003985
Girish Gowdrae95687a2021-09-08 16:30:58 -07003986func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3987 dh.mutexFlowMonitoringRoutineFlag.Lock()
3988 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003989 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"device-id": dh.device.Id, "flag": flag})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003990 dh.isFlowMonitoringRoutineActive[uniID] = flag
3991}
3992
3993func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3994 dh.mutexFlowMonitoringRoutineFlag.RLock()
3995 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3996 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00003997 log.Fields{"device-id": dh.device.Id, "isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003998 return dh.isFlowMonitoringRoutineActive[uniID]
3999}
4000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004001func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
4002 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004003
Maninder7961d722021-06-16 22:10:28 +05304004 connectStatus := voltha.ConnectStatus_UNREACHABLE
4005 operState := voltha.OperStatus_UNKNOWN
4006
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004007 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004008 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004009 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00004010 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004011 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004012 case success := <-dh.chReconcilingFinished:
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004013 logger.Debugw(ctx, "reconciling finished signal received",
4014 log.Fields{"device-id": dh.DeviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
4015 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
4016 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
4017 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
4018 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
4019 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
4020 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
4021 // However, a later refactoring of the functionality remains unaffected.
4022 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004023 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004024 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05304025 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004026 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05304027 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00004028 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05304030 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004031 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
4032 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304033 operState = voltha.OperStatus_ACTIVE
4034 } else {
4035 operState = voltha.OperStatus_ACTIVATING
4036 }
4037 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004038 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4039 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4040 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304041 operState = voltha.OperStatus_DISCOVERED
4042 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004043 onuDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004044 logger.Debugw(ctx, "Core DeviceStateUpdate",
4045 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304046 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004047 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004048 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004049 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004050 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004051 ConnStatus: connectStatus,
4052 OperStatus: operState,
4053 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304054 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004055 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304056 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004057 } else {
Maninderb5187552021-03-23 22:23:42 +05304058 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004059 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304060
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004061 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304062 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004063 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004064 } else {
4065 onuDevEntry.MutexPersOnuConfig.RLock()
4066 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4067 connectStatus = voltha.ConnectStatus_REACHABLE
4068 }
4069 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304070 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004071 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004072 }
mpagenko101ac942021-11-16 15:01:29 +00004073 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004074 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004075 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf7459252022-01-03 16:10:37 +00004076 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05304077
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004078 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304079 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004080 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004081 } else {
4082 onuDevEntry.MutexPersOnuConfig.RLock()
4083 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4084 connectStatus = voltha.ConnectStatus_REACHABLE
4085 }
4086 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304087 }
4088
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004089 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304090
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004091 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004092 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004093 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004094 dh.SetReconcilingReasonUpdate(false)
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004095 dh.SetReconcilingFirstPass(true)
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004096
4097 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
4098 logger.Errorw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
4099 } else {
4100 onuDevEntry.MutexReconciledTpInstances.Lock()
4101 onuDevEntry.ReconciledTpInstances = make(map[uint8]map[uint8]inter_adapter.TechProfileDownloadMessage)
4102 onuDevEntry.MutexReconciledTpInstances.Unlock()
4103 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004104 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004105 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004106 dh.mutexReconcilingFlag.Lock()
4107 if skipOnuConfig {
4108 dh.reconciling = cSkipOnuConfigReconciling
4109 } else {
4110 dh.reconciling = cOnuConfigReconciling
4111 }
4112 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004113}
4114
mpagenko101ac942021-11-16 15:01:29 +00004115func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004116 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4117 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004118 dh.sendChReconcileFinished(success)
4119 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4120 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4121 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004122 } else {
mpagenko101ac942021-11-16 15:01:29 +00004123 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004124 }
4125}
4126
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004127func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004128 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004129 defer dh.mutexReconcilingFlag.RUnlock()
4130 return dh.reconciling != cNoReconciling
4131}
4132
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004133func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004134 dh.mutexReconcilingFlag.RLock()
4135 defer dh.mutexReconcilingFlag.RUnlock()
4136 return dh.reconciling == cSkipOnuConfigReconciling
4137}
4138
Holger Hildebrandt7741f272022-01-18 08:17:39 +00004139func (dh *deviceHandler) SetReconcilingFirstPass(value bool) {
4140 dh.mutexReconcilingFirstPassFlag.Lock()
4141 dh.reconcilingFirstPass = value
4142 dh.mutexReconcilingFirstPassFlag.Unlock()
4143}
4144
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004145func (dh *deviceHandler) SetReconcilingReasonUpdate(value bool) {
4146 dh.mutexReconcilingReasonUpdate.Lock()
4147 dh.reconcilingReasonUpdate = value
4148 dh.mutexReconcilingReasonUpdate.Unlock()
4149}
4150
4151func (dh *deviceHandler) IsReconcilingReasonUpdate() bool {
4152 dh.mutexReconcilingReasonUpdate.RLock()
4153 defer dh.mutexReconcilingReasonUpdate.RUnlock()
4154 return dh.reconcilingReasonUpdate
4155}
4156
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004157func (dh *deviceHandler) getDeviceReason() uint8 {
4158 dh.mutexDeviceReason.RLock()
4159 value := dh.deviceReason
4160 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004161 return value
4162}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004163
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004164func (dh *deviceHandler) GetDeviceReasonString() string {
4165 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004166}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004167
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004168func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004169 dh.mutexReadyForOmciConfig.Lock()
4170 dh.readyForOmciConfig = flagValue
4171 dh.mutexReadyForOmciConfig.Unlock()
4172}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004173func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004174 dh.mutexReadyForOmciConfig.RLock()
4175 flagValue := dh.readyForOmciConfig
4176 dh.mutexReadyForOmciConfig.RUnlock()
4177 return flagValue
4178}
Maninder7961d722021-06-16 22:10:28 +05304179
4180func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
mpagenkoe4782082021-11-25 12:04:26 +00004181 if err := dh.ReasonUpdate(ctx, deviceReason, true); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304182 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004183 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304184 }
4185
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004186 logger.Debugw(ctx, "Core DeviceStateUpdate",
4187 log.Fields{"device-id": dh.device.Id, "connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004188 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004189 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004190 ConnStatus: connectStatus,
4191 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4192 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304193 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004194 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304195 }
4196}
khenaidoo7d3c5582021-08-11 18:09:44 -04004197
4198/*
4199Helper functions to communicate with Core
4200*/
4201
4202func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4203 cClient, err := dh.coreClient.GetCoreServiceClient()
4204 if err != nil || cClient == nil {
4205 return nil, err
4206 }
4207 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4208 defer cancel()
4209 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4210 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4211}
4212
khenaidoo42dcdfd2021-10-19 17:34:12 -04004213func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004214 cClient, err := dh.coreClient.GetCoreServiceClient()
4215 if err != nil || cClient == nil {
4216 return err
4217 }
4218 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4219 defer cancel()
4220 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004221 logger.Debugw(subCtx, "device-updated-in-core",
4222 log.Fields{"device-id": dh.device.Id, "device-state": deviceStateFilter, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004223 return err
4224}
4225
4226func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4227 cClient, err := dh.coreClient.GetCoreServiceClient()
4228 if err != nil || cClient == nil {
4229 return err
4230 }
4231 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4232 defer cancel()
4233 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004234 logger.Debugw(subCtx, "pmconfig-updated-in-core",
4235 log.Fields{"device-id": dh.device.Id, "pm-configs": pmConfigs, "error": err})
khenaidoo7d3c5582021-08-11 18:09:44 -04004236 return err
4237}
4238
4239func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4240 cClient, err := dh.coreClient.GetCoreServiceClient()
4241 if err != nil || cClient == nil {
4242 return err
4243 }
4244 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4245 defer cancel()
4246 _, err = cClient.DeviceUpdate(subCtx, device)
4247 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4248 return err
4249}
4250
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004251func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004252 cClient, err := dh.coreClient.GetCoreServiceClient()
4253 if err != nil || cClient == nil {
4254 return err
4255 }
4256 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4257 defer cancel()
4258 _, err = cClient.PortCreated(subCtx, port)
4259 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4260 return err
4261}
4262
khenaidoo42dcdfd2021-10-19 17:34:12 -04004263func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004264 cClient, err := dh.coreClient.GetCoreServiceClient()
4265 if err != nil || cClient == nil {
4266 return err
4267 }
4268 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4269 defer cancel()
4270 _, err = cClient.PortStateUpdate(subCtx, portState)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004271 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 -04004272 return err
4273}
4274
khenaidoo42dcdfd2021-10-19 17:34:12 -04004275func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004276 cClient, err := dh.coreClient.GetCoreServiceClient()
4277 if err != nil || cClient == nil {
4278 return err
4279 }
4280 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4281 defer cancel()
4282 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004283 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 -04004284 return err
4285}
4286
4287/*
4288Helper functions to communicate with parent adapter
4289*/
4290
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004291func (dh *deviceHandler) GetTechProfileInstanceFromParentAdapter(ctx context.Context, aUniID uint8,
4292 aTpPath string) (*ia.TechProfileDownloadMessage, error) {
4293
4294 var request = ia.TechProfileInstanceRequestMessage{
4295 DeviceId: dh.DeviceID,
4296 TpInstancePath: aTpPath,
4297 ParentDeviceId: dh.parentID,
4298 ParentPonPort: dh.device.ParentPortNo,
4299 OnuId: dh.device.ProxyAddress.OnuId,
4300 UniId: uint32(aUniID),
4301 }
4302
4303 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(dh.device.ProxyAddress.AdapterEndpoint)
khenaidoo7d3c5582021-08-11 18:09:44 -04004304 if err != nil || pgClient == nil {
4305 return nil, err
4306 }
4307 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4308 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004309 logger.Debugw(subCtx, "get-tech-profile-instance",
4310 log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": dh.device.ProxyAddress.AdapterEndpoint})
Holger Hildebrandt9afc1582021-11-30 16:10:19 +00004311 return pgClient.GetTechProfileInstance(subCtx, &request)
khenaidoo7d3c5582021-08-11 18:09:44 -04004312}
4313
Girish Gowdrae95687a2021-09-08 16:30:58 -07004314// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4315// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4316func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4317 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4318 dh.setFlowMonitoringIsRunning(uniID, true)
4319 for {
4320 select {
4321 // block on the channel to receive an incoming flow
4322 // process the flow completely before proceeding to handle the next flow
4323 case flowCb := <-dh.flowCbChan[uniID]:
4324 startTime := time.Now()
4325 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4326 respChan := make(chan error)
4327 if flowCb.addFlow {
4328 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4329 } else {
4330 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4331 }
4332 // Block on response and tunnel it back to the caller
4333 *flowCb.respChan <- <-respChan
4334 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4335 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4336 case <-dh.stopFlowMonitoringRoutine[uniID]:
4337 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4338 dh.setFlowMonitoringIsRunning(uniID, false)
4339 return
4340 }
4341 }
4342}
4343
kesavand011d5162021-11-25 19:21:06 +05304344func (dh *deviceHandler) SendOnuSwSectionsOfWindow(ctx context.Context, parentEndpoint string, request *ia.OmciMessages) error {
4345 request.ParentDeviceId = dh.GetProxyAddressID()
4346 request.ChildDeviceId = dh.DeviceID
4347 request.ProxyAddress = dh.GetProxyAddress()
4348 request.ConnectStatus = common.ConnectStatus_REACHABLE
4349
4350 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4351 if err != nil || pgClient == nil {
4352 return err
4353 }
4354 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4355 defer cancel()
4356 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4357 _, err = pgClient.ProxyOmciRequests(subCtx, request)
4358 if err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00004359 logger.Errorw(ctx, "omci-failure", log.Fields{"device-id": dh.device.Id, "request": request, "error": err,
4360 "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
kesavand011d5162021-11-25 19:21:06 +05304361 }
4362 return err
4363}
4364
khenaidoo42dcdfd2021-10-19 17:34:12 -04004365func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004366 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4367 if err != nil || pgClient == nil {
4368 return err
4369 }
4370 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4371 defer cancel()
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004372 logger.Debugw(subCtx, "send-omci-request", log.Fields{"device-id": dh.device.Id, "request": request, "parent-endpoint": parentEndpoint})
khenaidoo7d3c5582021-08-11 18:09:44 -04004373 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4374 if err != nil {
Holger Hildebrandtba6fbe82021-12-03 14:29:42 +00004375 logger.Errorw(ctx, "omci-failure",
4376 log.Fields{"device-id": dh.device.Id, "request": request, "error": err, "request-parent": request.ParentDeviceId,
4377 "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
khenaidoo7d3c5582021-08-11 18:09:44 -04004378 }
4379 return err
4380}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004381
4382// GetDeviceID - TODO: add comment
4383func (dh *deviceHandler) GetDeviceID() string {
4384 return dh.DeviceID
4385}
4386
4387// GetProxyAddressID - TODO: add comment
4388func (dh *deviceHandler) GetProxyAddressID() string {
4389 return dh.device.ProxyAddress.GetDeviceId()
4390}
4391
4392// GetProxyAddressType - TODO: add comment
4393func (dh *deviceHandler) GetProxyAddressType() string {
4394 return dh.device.ProxyAddress.GetDeviceType()
4395}
4396
4397// GetProxyAddress - TODO: add comment
4398func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4399 return dh.device.ProxyAddress
4400}
4401
4402// GetEventProxy - TODO: add comment
4403func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4404 return dh.EventProxy
4405}
4406
4407// GetOmciTimeout - TODO: add comment
4408func (dh *deviceHandler) GetOmciTimeout() int {
4409 return dh.pOpenOnuAc.omciTimeout
4410}
4411
4412// GetAlarmAuditInterval - TODO: add comment
4413func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4414 return dh.pOpenOnuAc.alarmAuditInterval
4415}
4416
4417// GetDlToOnuTimeout4M - TODO: add comment
4418func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4419 return dh.pOpenOnuAc.dlToOnuTimeout4M
4420}
4421
4422// GetUniEntityMap - TODO: add comment
4423func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4424 return &dh.uniEntityMap
4425}
4426
4427// GetPonPortNumber - TODO: add comment
4428func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4429 return &dh.ponPortNumber
4430}
4431
4432// GetUniVlanConfigFsm - TODO: add comment
4433func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004434 dh.lockVlanConfig.RLock()
4435 value := dh.UniVlanConfigFsmMap[uniID]
4436 dh.lockVlanConfig.RUnlock()
4437 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004438}
4439
4440// GetOnuAlarmManager - TODO: add comment
4441func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4442 return dh.pAlarmMgr
4443}
4444
4445// GetOnuMetricsManager - TODO: add comment
4446func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4447 return dh.pOnuMetricsMgr
4448}
4449
4450// GetOnuTP - TODO: add comment
4451func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4452 return dh.pOnuTP
4453}
4454
4455// GetBackendPathPrefix - TODO: add comment
4456func (dh *deviceHandler) GetBackendPathPrefix() string {
4457 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4458}
4459
4460// GetOnuIndication - TODO: add comment
4461func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4462 return dh.pOnuIndication
4463}
4464
4465// RLockMutexDeletionInProgressFlag - TODO: add comment
4466func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4467 dh.mutexDeletionInProgressFlag.RLock()
4468}
4469
4470// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4471func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4472 dh.mutexDeletionInProgressFlag.RUnlock()
4473}
4474
4475// GetDeletionInProgress - TODO: add comment
4476func (dh *deviceHandler) GetDeletionInProgress() bool {
4477 return dh.deletionInProgress
4478}
4479
4480// GetPmConfigs - TODO: add comment
4481func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4482 return dh.pmConfigs
4483}
4484
4485// GetDeviceType - TODO: add comment
4486func (dh *deviceHandler) GetDeviceType() string {
4487 return dh.DeviceType
4488}
4489
4490// GetLogicalDeviceID - TODO: add comment
4491func (dh *deviceHandler) GetLogicalDeviceID() string {
4492 return dh.logicalDeviceID
4493}
4494
4495// GetDevice - TODO: add comment
4496func (dh *deviceHandler) GetDevice() *voltha.Device {
4497 return dh.device
4498}
4499
4500// GetMetricsEnabled - TODO: add comment
4501func (dh *deviceHandler) GetMetricsEnabled() bool {
4502 return dh.pOpenOnuAc.MetricsEnabled
4503}
4504
4505// InitPmConfigs - TODO: add comment
4506func (dh *deviceHandler) InitPmConfigs() {
4507 dh.pmConfigs = &voltha.PmConfigs{}
4508}
4509
4510// GetUniPortMask - TODO: add comment
4511func (dh *deviceHandler) GetUniPortMask() int {
4512 return dh.pOpenOnuAc.config.UniPortMask
4513}
Holger Hildebrandtb314f442021-11-24 12:03:10 +00004514
4515func (dh *deviceHandler) anyTpPathExists(aTpPathMap map[uint8]string) bool {
4516 tpPathFound := false
4517 for _, tpPath := range aTpPathMap {
4518 if tpPath != "" {
4519 tpPathFound = true
4520 }
4521 }
4522 return tpPathFound
4523}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00004524
4525// PrepareForGarbageCollection - remove references to prepare for garbage collection
4526func (dh *deviceHandler) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
4527 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
4528
4529 // Note: This function must be called as a goroutine to prevent blocking of further processing!
4530 // first let the objects rest for some time to give all asynchronously started
4531 // cleanup routines a chance to come to an end
4532 time.Sleep(5 * time.Second)
4533
4534 if dh.pOnuTP != nil {
4535 dh.pOnuTP.PrepareForGarbageCollection(ctx, aDeviceID)
4536 }
4537 if dh.pOnuMetricsMgr != nil {
4538 dh.pOnuMetricsMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4539 }
4540 if dh.pAlarmMgr != nil {
4541 dh.pAlarmMgr.PrepareForGarbageCollection(ctx, aDeviceID)
4542 }
4543 if dh.pSelfTestHdlr != nil {
4544 dh.pSelfTestHdlr.PrepareForGarbageCollection(ctx, aDeviceID)
4545 }
4546 if dh.pLockStateFsm != nil {
4547 dh.pLockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4548 }
4549 if dh.pUnlockStateFsm != nil {
4550 dh.pUnlockStateFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4551 }
4552 if dh.pOnuUpradeFsm != nil {
4553 dh.pOnuUpradeFsm.PrepareForGarbageCollection(ctx, aDeviceID)
4554 }
4555 if dh.pOnuOmciDevice != nil {
4556 dh.pOnuOmciDevice.PrepareForGarbageCollection(ctx, aDeviceID)
4557 }
4558 for k, v := range dh.UniVlanConfigFsmMap {
4559 v.PrepareForGarbageCollection(ctx, aDeviceID)
4560 delete(dh.UniVlanConfigFsmMap, k)
4561 }
4562 dh.pOnuOmciDevice = nil
4563 dh.pOnuTP = nil
4564 dh.pOnuMetricsMgr = nil
4565 dh.pAlarmMgr = nil
4566 dh.pSelfTestHdlr = nil
4567 dh.pLockStateFsm = nil
4568 dh.pUnlockStateFsm = nil
4569 dh.pOnuUpradeFsm = nil
4570}