blob: 4274e90fbf7b55463e28f08ec70d7394f7afdd6a [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"
khenaidoo7d3c5582021-08-11 18:09:44 -040047 vc "github.com/opencord/voltha-protos/v5/go/common"
khenaidoo42dcdfd2021-10-19 17:34:12 -040048 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040049 "github.com/opencord/voltha-protos/v5/go/extension"
khenaidoo42dcdfd2021-10-19 17:34:12 -040050 ia "github.com/opencord/voltha-protos/v5/go/inter_adapter"
khenaidoo7d3c5582021-08-11 18:09:44 -040051 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenko59862f02021-10-11 08:53:18 +000052 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040053 oop "github.com/opencord/voltha-protos/v5/go/openolt"
mpagenko59862f02021-10-11 08:53:18 +000054 "github.com/opencord/voltha-protos/v5/go/tech_profile"
khenaidoo7d3c5582021-08-11 18:09:44 -040055 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000056)
57
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000058const (
mpagenko101ac942021-11-16 15:01:29 +000059 //constants for reconcile flow check channel
60 cWaitReconcileFlowAbortOnSuccess = 0xFFFD
61 cWaitReconcileFlowAbortOnError = 0xFFFE
62 cWaitReconcileFlowNoActivity = 0xFFFF
63)
64
65const (
66 // constants for timeouts
mpagenko38662d02021-08-11 09:45:19 +000067 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000068)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000069
mpagenko1cc3cb42020-07-27 15:24:38 +000070const (
mpagenko44bd8362021-11-15 11:40:05 +000071 // dummy constant - irregular value for ConnState - used to avoiding setting this state in the updateDeviceState()
72 // should better be defined in voltha protobuf or best solution would be to define an interface to just set the OperState
73 // as long as such is not available by the libraries - use this workaround
74 connectStatusINVALID = 255 // as long as not used as key in voltha.ConnectStatus_Types_name
75)
76
77const (
mpagenko1cc3cb42020-07-27 15:24:38 +000078 // events of Device FSM
79 devEvDeviceInit = "devEvDeviceInit"
80 devEvGrpcConnected = "devEvGrpcConnected"
81 devEvGrpcDisconnected = "devEvGrpcDisconnected"
82 devEvDeviceUpInd = "devEvDeviceUpInd"
83 devEvDeviceDownInd = "devEvDeviceDownInd"
84)
85const (
86 // states of Device FSM
87 devStNull = "devStNull"
88 devStDown = "devStDown"
89 devStInit = "devStInit"
90 devStConnected = "devStConnected"
91 devStUp = "devStUp"
92)
93
Holger Hildebrandt24d51952020-05-04 14:03:42 +000094//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
95const (
Himani Chawla4d908332020-08-31 12:30:20 +053096 pon = voltha.EventSubCategory_PON
97 //olt = voltha.EventSubCategory_OLT
98 //ont = voltha.EventSubCategory_ONT
99 //onu = voltha.EventSubCategory_ONU
100 //nni = voltha.EventSubCategory_NNI
101 //service = voltha.EventCategory_SERVICE
102 //security = voltha.EventCategory_SECURITY
103 equipment = voltha.EventCategory_EQUIPMENT
104 //processing = voltha.EventCategory_PROCESSING
105 //environment = voltha.EventCategory_ENVIRONMENT
106 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000107)
108
109const (
110 cEventObjectType = "ONU"
111)
112const (
113 cOnuActivatedEvent = "ONU_ACTIVATED"
114)
115
mpagenkof1fc3862021-02-16 10:09:52 +0000116type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000118 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000119}
120
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000121var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
122 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
123 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
124 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
125 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
126 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
127 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
128 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
129 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000130}
131
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000132const (
133 cNoReconciling = iota
134 cOnuConfigReconciling
135 cSkipOnuConfigReconciling
136)
137
Girish Gowdrae95687a2021-09-08 16:30:58 -0700138// FlowCb is the flow control block containing flow add/delete information along with a response channel
139type FlowCb struct {
140 ctx context.Context // Flow handler context
141 addFlow bool // if true flow to be added, else removed
142 flowItem *of.OfpFlowStats
143 uniPort *cmn.OnuUniPort
khenaidoo42dcdfd2021-10-19 17:34:12 -0400144 flowMetaData *of.FlowMetadata
Girish Gowdrae95687a2021-09-08 16:30:58 -0700145 respChan *chan error // channel to report the Flow handling error
146}
147
Himani Chawla6d2ae152020-09-02 13:11:20 +0530148//deviceHandler will interact with the ONU ? device.
149type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000150 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000151 DeviceType string
152 adminState string
153 device *voltha.Device
154 logicalDeviceID string
155 ProxyAddressID string
156 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530157 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000158 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000159
khenaidoo7d3c5582021-08-11 18:09:44 -0400160 coreClient *vgrpc.Client
161 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000162
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800163 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400164 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800165
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000166 pOpenOnuAc *OpenONUAC
167 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530168 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000169 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000170 pOnuOmciDevice *mib.OnuDeviceEntry
171 pOnuTP *avcfg.OnuUniTechProf
172 pOnuMetricsMgr *pmmgr.OnuMetricsManager
173 pAlarmMgr *almgr.OnuAlarmManager
174 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000175 exitChannel chan int
176 lockDevice sync.RWMutex
177 pOnuIndication *oop.OnuIndication
178 deviceReason uint8
179 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000180 pLockStateFsm *uniprt.LockStateFsm
181 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000182
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000183 //flowMgr *OpenOltFlowMgr
184 //eventMgr *OpenOltEventMgr
185 //resourceMgr *rsrcMgr.OpenOltResourceMgr
186
187 //discOnus sync.Map
188 //onus sync.Map
189 //portStats *OpenOltStatisticsMgr
mpagenko101ac942021-11-16 15:01:29 +0000190 collectorIsRunning bool
191 mutexCollectorFlag sync.RWMutex
192 stopCollector chan bool
193 alarmManagerIsRunning bool
194 mutextAlarmManagerFlag sync.RWMutex
195 stopAlarmManager chan bool
196 stopHeartbeatCheck chan bool
197 uniEntityMap cmn.OnuUniPortMap
198 mutexKvStoreContext sync.Mutex
199 lockVlanConfig sync.RWMutex
200 lockVlanAdd sync.RWMutex
201 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
202 lockUpgradeFsm sync.RWMutex
203 pOnuUpradeFsm *swupg.OnuUpgradeFsm
204 upgradeCanceled bool
205 reconciling uint8
206 mutexReconcilingFlag sync.RWMutex
207 chUniVlanConfigReconcilingDone chan uint16 //channel to indicate that VlanConfig reconciling for a specific UNI has been finished
208 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
209 reconcileExpiryComplete time.Duration
210 reconcileExpiryVlanConfig time.Duration
211 mutexReadyForOmciConfig sync.RWMutex
212 readyForOmciConfig bool
213 deletionInProgress bool
214 mutexDeletionInProgressFlag sync.RWMutex
215 pLastUpgradeImageState *voltha.ImageState
216 upgradeFsmChan chan struct{}
Girish Gowdrae95687a2021-09-08 16:30:58 -0700217
218 flowCbChan []chan FlowCb
219 mutexFlowMonitoringRoutineFlag sync.RWMutex
220 stopFlowMonitoringRoutine []chan bool // length of slice equal to number of uni ports
221 isFlowMonitoringRoutineActive []bool // length of slice equal to number of uni ports
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000222}
223
Himani Chawla6d2ae152020-09-02 13:11:20 +0530224//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400225func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530226 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400227 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000228 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400229 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000230 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000231 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000232 dh.DeviceType = cloned.Type
233 dh.adminState = "up"
234 dh.device = cloned
235 dh.pOpenOnuAc = adapter
236 dh.exitChannel = make(chan int, 1)
237 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000238 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000239 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000240 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530241 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530242 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.stopHeartbeatCheck = make(chan bool, 2)
244 //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 +0000245 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000247 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000248 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000249 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000251 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000252 dh.chReconcilingFinished = make(chan bool)
mpagenko101ac942021-11-16 15:01:29 +0000253 dh.reconcileExpiryComplete = adapter.maxTimeoutReconciling //assumption is to have it as duration in s!
254 rECSeconds := int(dh.reconcileExpiryComplete / time.Second)
255 if rECSeconds < 2 {
256 dh.reconcileExpiryComplete = time.Duration(2) * time.Second //ensure a minimum expiry time of 2s for complete reconciling
257 rECSeconds = 2
258 }
259 rEVCSeconds := rECSeconds / 2
260 dh.reconcileExpiryVlanConfig = time.Duration(rEVCSeconds) * time.Second //set this duration to some according lower value
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000261 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000262 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000263 dh.pLastUpgradeImageState = &voltha.ImageState{
264 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
265 Reason: voltha.ImageState_UNKNOWN_ERROR,
266 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
267 }
268 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000269
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800270 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
271 dh.pmConfigs = cloned.PmConfigs
272 } /* else {
273 // will be populated when onu_metrics_mananger is initialized.
274 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800275
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276 // Device related state machine
277 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000278 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000280 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
281 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
282 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
283 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
284 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000285 },
286 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000287 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
288 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
289 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
290 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
291 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
292 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
293 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
294 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 },
296 )
mpagenkoaf801632020-07-03 10:00:42 +0000297
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298 return &dh
299}
300
Himani Chawla6d2ae152020-09-02 13:11:20 +0530301// start save the device to the data model
302func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000303 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000304 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306}
307
Himani Chawla4d908332020-08-31 12:30:20 +0530308/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530310func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 logger.Debug("stopping-device-handler")
312 dh.exitChannel <- 1
313}
Himani Chawla4d908332020-08-31 12:30:20 +0530314*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000315
316// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530317// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318
Girish Gowdrae0140f02021-02-02 16:55:09 -0800319//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530320func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400321 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000324 if dh.pDeviceStateFsm.Is(devStNull) {
325 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800329 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
330 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800331 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400332 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800334 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800335 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000336 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338 }
339
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000340}
341
khenaidoo42dcdfd2021-10-19 17:34:12 -0400342func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ia.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000343 /* 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 +0530344 //assuming omci message content is hex coded!
345 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000347 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000348 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000349 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000351 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000353 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400354 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": msg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530355 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000356 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
357 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530358}
359
khenaidoo42dcdfd2021-10-19 17:34:12 -0400360func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ia.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000361 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000362
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000363 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000364 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000365 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
366 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 if dh.pOnuTP == nil {
369 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 log.Fields{"device-id": dh.DeviceID})
372 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000374 if !dh.IsReadyForOmciConfig() {
375 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
376 "device-state": dh.GetDeviceReasonString()})
377 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530378 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000379 //previous state test here was just this one, now extended for more states to reject the SetRequest:
380 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
381 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530382
Himani Chawla26e555c2020-08-31 12:30:20 +0530383 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000384 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
385 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 dh.pOnuTP.LockTpProcMutex()
387 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000388
mpagenko44bd8362021-11-15 11:40:05 +0000389 if techProfMsg.UniId >= platform.MaxUnisPerOnu {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000390 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000391 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 }
393 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000394 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800395 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700396 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800397 return err
398 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700399 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000400
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000401 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530402
Girish Gowdra50e56422021-06-01 16:46:04 -0700403 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400404 case *ia.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700405 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
406 // if there has been some change for some uni TechProfilePath
407 //in order to allow concurrent calls to other dh instances we do not wait for execution here
408 //but doing so we can not indicate problems to the caller (who does what with that then?)
409 //by now we just assume straightforward successful execution
410 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
411 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530412
Girish Gowdra50e56422021-06-01 16:46:04 -0700413 // deadline context to ensure completion of background routines waited for
414 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
415 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
416 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000418 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700419
420 var wg sync.WaitGroup
421 wg.Add(1) // for the 1 go routine to finish
422 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000423 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700424 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
426 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 -0700427 return tpErr
428 }
429 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
430 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000431 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700432 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000433 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700434 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000435 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
436 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 -0700437 return kvErr
438 }
439 return nil
440 default:
441 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
442 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700443 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530444 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700446 logger.Debugw(ctx, "onu-uni-tp-path-not-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530447 return nil
448}
449
khenaidoo42dcdfd2021-10-19 17:34:12 -0400450func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ia.DeleteGemPortMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000451 logger.Infow(ctx, "delete-gem-port-request start", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530452
453 if dh.pOnuTP == nil {
454 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000455 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000456 log.Fields{"device-id": dh.DeviceID})
457 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530458 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530459 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000460 dh.pOnuTP.LockTpProcMutex()
461 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530462
mpagenko0f543222021-11-03 16:24:14 +0000463 if delGemPortMsg.UniId >= platform.MaxUnisPerOnu {
464 logger.Errorw(ctx, "delete-gem-port UniId exceeds range", log.Fields{
465 "device-id": dh.DeviceID, "uni-id": delGemPortMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000467 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468 }
469 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800471 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000472 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
473 "device-id": dh.DeviceID, "err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800474 return err
475 }
mpagenko0f543222021-11-03 16:24:14 +0000476 logger.Infow(ctx, "delete-gem-port-request", log.Fields{
477 "device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000478 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000479
Mahir Gunyel9545be22021-07-04 15:53:16 -0700480 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482
Himani Chawla26e555c2020-08-31 12:30:20 +0530483}
484
khenaidoo42dcdfd2021-10-19 17:34:12 -0400485func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ia.DeleteTcontMessage) error {
mpagenko0f543222021-11-03 16:24:14 +0000486 logger.Infow(ctx, "delete-tcont-request start", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000488 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000489 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
491 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000492 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 if dh.pOnuTP == nil {
494 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000495 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000496 log.Fields{"device-id": dh.DeviceID})
497 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530498 }
499
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000501 dh.pOnuTP.LockTpProcMutex()
502 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000503
mpagenko0f543222021-11-03 16:24:14 +0000504 if delTcontMsg.UniId >= platform.MaxUnisPerOnu {
505 logger.Errorw(ctx, "delete-tcont UniId exceeds range", log.Fields{
506 "device-id": dh.DeviceID, "uni-id": delTcontMsg.UniId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000508 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000509 }
510 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700511 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000512 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800513 if err != nil {
mpagenko0f543222021-11-03 16:24:14 +0000514 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{
515 "device-id": dh.DeviceID, "err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800516 return err
517 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000520 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530521
Mahir Gunyel9545be22021-07-04 15:53:16 -0700522 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000523 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000524
Mahir Gunyel9545be22021-07-04 15:53:16 -0700525}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526
Mahir Gunyel9545be22021-07-04 15:53:16 -0700527func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000528 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
529 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700530 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000531 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
532 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530533 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700534 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000535 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700536 resourceName = "Gem"
537 } else {
538 resourceName = "Tcont"
539 }
540
541 // deadline context to ensure completion of background routines waited for
542 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
543 dctx, cancel := context.WithDeadline(context.Background(), deadline)
544
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000545 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700546
547 var wg sync.WaitGroup
548 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700550 resource, entryID, &wg)
551 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
553 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700554 return err
555 }
556
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
558 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
559 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
560 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700561 var wg2 sync.WaitGroup
562 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
563 wg2.Add(1)
564 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
566 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700567 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
569 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700570 return err
571 }
572 }
573 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700575 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530576 return nil
577}
578
mpagenkodff5dda2020-08-28 11:52:01 +0000579//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000580func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400581 apOfFlowChanges *of.FlowChanges,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400582 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *of.FlowMetadata) error {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700583 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "flow": apOfFlowChanges, "metadata": apFlowMetaData})
584 var errorsList []error
585 var retError error
mpagenko01e726e2020-10-23 09:45:29 +0000586 //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 +0000587 if apOfFlowChanges.ToRemove != nil {
588 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000589 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 "device-id": dh.DeviceID})
592 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700593 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000594 continue
595 }
596 flowInPort := flow.GetInPort(flowItem)
597 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
599 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700600 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000601 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000603 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000604 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000605 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000607 continue
608 } else {
609 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000611 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
612 loUniPort = uniPort
613 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000616 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000617 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700618 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000619 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000620 }
621 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
624 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625
626 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
627 // Step1 : Fill flowControlBlock
628 // Step2 : Push the flowControlBlock to ONU channel
629 // Step3 : Wait on response channel for response
630 // Step4 : Return error value
631 startTime := time.Now()
632 respChan := make(chan error)
633 flowCb := FlowCb{
634 ctx: ctx,
635 addFlow: false,
636 flowItem: flowItem,
637 flowMetaData: nil,
638 uniPort: loUniPort,
639 respChan: &respChan,
640 }
641 dh.flowCbChan[loUniPort.UniID] <- flowCb
642 logger.Infow(ctx, "process-flow-remove-start", log.Fields{"device-id": dh.DeviceID})
643 // Wait on the channel for flow handlers return value
644 retError = <-respChan
645 logger.Infow(ctx, "process-flow-remove-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
646 if retError != nil {
647 logger.Warnw(ctx, "flow-delete processing error: continuing on checking further flows",
648 log.Fields{"device-id": dh.DeviceID, "error": retError})
649 errorsList = append(errorsList, retError)
650 continue
651 }
652 } else {
653 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
654 errorsList = append(errorsList, retError)
mpagenkodff5dda2020-08-28 11:52:01 +0000655 }
656 }
657 }
658 }
mpagenko01e726e2020-10-23 09:45:29 +0000659 if apOfFlowChanges.ToAdd != nil {
660 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
661 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000663 "device-id": dh.DeviceID})
664 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000666 continue
667 }
668 flowInPort := flow.GetInPort(flowItem)
669 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000670 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
671 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000673 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000675 } else if flowInPort == dh.ponPortNumber {
676 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000679 continue
680 } else {
681 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000682 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000683 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
684 loUniPort = uniPort
685 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000687 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000688 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000689 flowInPort, dh.DeviceID)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700690 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000691 continue
mpagenko01e726e2020-10-23 09:45:29 +0000692 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000693 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
694 // if not, we just throw some error here to have an indication about that, if we really need to support that
695 // then we would need to create some means to activate the internal stored flows
696 // after the device gets active automatically (and still with its dependency to the TechProfile)
697 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
698 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000699 if !dh.IsReadyForOmciConfig() {
700 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
701 "last device-reason": dh.GetDeviceReasonString()})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700702 retError = fmt.Errorf("improper device state on device %s", dh.DeviceID)
703 errorsList = append(errorsList, retError)
704 continue
mpagenkofc4f56e2020-11-04 17:17:49 +0000705 }
706
mpagenko01e726e2020-10-23 09:45:29 +0000707 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000709 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
710 "uniPortName": loUniPort.Name})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700711 if dh.GetFlowMonitoringIsRunning(loUniPort.UniID) {
712 // Step1 : Fill flowControlBlock
713 // Step2 : Push the flowControlBlock to ONU channel
714 // Step3 : Wait on response channel for response
715 // Step4 : Return error value
716 startTime := time.Now()
717 respChan := make(chan error)
718 flowCb := FlowCb{
719 ctx: ctx,
720 addFlow: true,
721 flowItem: flowItem,
722 flowMetaData: apFlowMetaData,
723 uniPort: loUniPort,
724 respChan: &respChan,
725 }
726 dh.flowCbChan[loUniPort.UniID] <- flowCb
727 logger.Infow(ctx, "process-flow-add-start", log.Fields{"device-id": dh.DeviceID})
728 // Wait on the channel for flow handlers return value
729 retError = <-respChan
730 logger.Infow(ctx, "process-flow-add-end", log.Fields{"device-id": dh.DeviceID, "err": retError, "totalTimeSeconds": time.Since(startTime).Seconds()})
731 if retError != nil {
732 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
733 log.Fields{"device-id": dh.DeviceID, "error": retError})
734 errorsList = append(errorsList, retError)
735 continue
736 }
737 } else {
738 retError = fmt.Errorf("flow-handler-routine-not-active-for-onu--device-id-%v", dh.DeviceID)
739 errorsList = append(errorsList, retError)
mpagenko01e726e2020-10-23 09:45:29 +0000740 }
741 }
742 }
743 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700744 if len(errorsList) > 0 {
745 logger.Errorw(ctx, "error-processing-flow", log.Fields{"device-id": dh.DeviceID, "errList": errorsList})
746 return fmt.Errorf("errors-installing-one-or-more-flows-groups, errors:%v", errorsList)
747 }
748 return nil
mpagenkodff5dda2020-08-28 11:52:01 +0000749}
750
Himani Chawla6d2ae152020-09-02 13:11:20 +0530751//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000752//following are the expected device states after this activity:
753//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
754// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
756 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000757
mpagenko900ee4b2020-10-12 11:56:34 +0000758 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000759 //note that disableDevice sequences in some 'ONU active' state may yield also
760 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000761 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000762 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000763 //disable-device shall be just a UNi/ONU-G related admin state setting
764 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000765
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000766 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000767 // disable UNI ports/ONU
768 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
769 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000770 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000771 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000772 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000774 }
775 } else {
mpagenko44bd8362021-11-15 11:40:05 +0000776 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000777 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +0000778 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -0400779 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000780 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +0000781 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -0400782 OperStatus: voltha.OperStatus_UNKNOWN,
783 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000784 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000786 }
mpagenko01e726e2020-10-23 09:45:29 +0000787 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000788
789 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000791 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300792 }
793}
794
Himani Chawla6d2ae152020-09-02 13:11:20 +0530795//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
797 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000798
mpagenkoaa3afe92021-05-21 16:20:58 +0000799 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000800 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
801 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
802 // for real ONU's that should have nearly no influence
803 // Note that for real ONU's there is anyway a problematic situation with following sequence:
804 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
805 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
806 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000807 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000808
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000809 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000810 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000811 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000814 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000816 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300817}
818
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000820 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000821
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000823 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000824 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 return
826 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000827 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000828 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000829 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000830 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000831 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000832 }
mpagenko101ac942021-11-16 15:01:29 +0000833 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000834 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000835 }
Himani Chawla4d908332020-08-31 12:30:20 +0530836 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000837 pDevEntry.MutexPersOnuConfig.RLock()
838 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
839 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
840 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
841 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
842 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000844}
845
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000846func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
847 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000848
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000849 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000850 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
852 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000853 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000854 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000855 return
856 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 dh.pOnuTP.LockTpProcMutex()
858 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000860 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000861 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000862 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
863 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000865 log.Fields{"device-id": dh.DeviceID})
866 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000867 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000868 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000869 return
870 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000871 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700872 techProfsFound := false
873 techProfInstLoadFailed := false
874outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000875 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000876 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
877 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000878 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000879 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000880 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000881 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000882 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
883 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000884 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000885 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000886 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700887 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800888 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700889 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400890 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
891 dh.device.ProxyAddress.AdapterEndpoint,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400892 &ia.TechProfileInstanceRequestMessage{
khenaidoo7d3c5582021-08-11 18:09:44 -0400893 DeviceId: dh.device.Id,
894 TpInstancePath: uniData.PersTpPathMap[tpID],
895 ParentDeviceId: dh.parentID,
896 ParentPonPort: dh.device.ParentPortNo,
897 OnuId: dh.device.ProxyAddress.OnuId,
898 UniId: uint32(uniData.PersUniID),
899 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700900 if err != nil || iaTechTpInst == nil {
901 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000902 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID, "err": err})
Girish Gowdra50e56422021-06-01 16:46:04 -0700903 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
904 break outerLoop
905 }
906 var tpInst tech_profile.TechProfileInstance
907 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo42dcdfd2021-10-19 17:34:12 -0400908 case *ia.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700909 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000910 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700912 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000913 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700915 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
916 break outerLoop
917 }
918
Girish Gowdra041dcb32020-11-16 16:54:30 -0800919 // deadline context to ensure completion of background routines waited for
920 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
921 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000922 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000923
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000924 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800925 var wg sync.WaitGroup
926 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000927 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000928 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000929 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
930 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700931 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
932 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800933 }
mpagenko2dc896e2021-08-02 12:03:59 +0000934 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000935 if len(uniData.PersFlowParams) != 0 {
936 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000937 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000938 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000939 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000940 } // for all UNI entries from SOnuPersistentData
941 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
942 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000943 }
mpagenko2dc896e2021-08-02 12:03:59 +0000944
945 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
946 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
947}
948
949func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
950 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
951 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 log.Fields{"device-id": dh.DeviceID})
954 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000955 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000956 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 return
958 }
mpagenko2dc896e2021-08-02 12:03:59 +0000959 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
mpagenko101ac942021-11-16 15:01:29 +0000961 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Girish Gowdra50e56422021-06-01 16:46:04 -0700962 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000963 } else if dh.IsSkipOnuConfigReconciling() {
964 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000965 }
mpagenko2dc896e2021-08-02 12:03:59 +0000966 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000967 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 log.Fields{"device-id": dh.DeviceID})
969 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000970 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000971 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000972 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000973}
974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
976 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000977
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000979 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
981 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000982 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000983 }
mpagenko101ac942021-11-16 15:01:29 +0000984 //else we don't stop the device handler reconciling in constellation with omci configuration
985 // to avoid unintented state update to rwCore due to still running background processes
986 // such is e.g. possible in TT scenarios with multiple techProfiles as currently the end of processing
987 // of all techProfiles is not awaited (ready on first TP done event)
988 // (applicable to all according code points below)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000989 return
990 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000991
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000992 pDevEntry.MutexPersOnuConfig.RLock()
993 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
994 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000995 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000996 log.Fields{"device-id": dh.DeviceID})
997 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +0000998 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000999 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001000 return
1001 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001002 flowsFound := false
mpagenko101ac942021-11-16 15:01:29 +00001003 var uniVlanConfigEntries []uint8
1004 var loWaitGroupWTO cmn.WaitGroupWithTimeOut
1005
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001006 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001007 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1008 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001009 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001010 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001011 continue
1012 }
1013 if len(uniData.PersTpPathMap) == 0 {
mpagenko101ac942021-11-16 15:01:29 +00001014 logger.Warnw(ctx, "reconciling flows - but no TPs stored for uniID, abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001015 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001016 // It doesn't make sense to configure any flows if no TPs are available
1017 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001018 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1020 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +00001021 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001023
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001024 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001025 var exist bool
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07001026 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001027 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001028 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
1029 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
1030 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001031 dh.stopReconciling(ctx, false, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001032 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001033 return
1034 }
mpagenko101ac942021-11-16 15:01:29 +00001035 //needed to split up function due to sca complexity
1036 dh.updateReconcileFlowConfig(ctx, uniPort, uniData.PersFlowParams, uniVlanConfigEntries, &loWaitGroupWTO, &flowsFound)
1037
mpagenko2dc896e2021-08-02 12:03:59 +00001038 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
mpagenko101ac942021-11-16 15:01:29 +00001039 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
1041 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001042 // this can't be used as global finished reconciling flag because
1043 // assumes is getting called before the state machines for the last flow is completed,
1044 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001045 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
1046 } // for all UNI entries from SOnuPersistentData
1047 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +00001048
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001049 if !flowsFound {
1050 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 log.Fields{"device-id": dh.DeviceID})
1052 if !dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001053 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001054 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001055 return
1056 }
mpagenko101ac942021-11-16 15:01:29 +00001057
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001058 if dh.IsSkipOnuConfigReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00001059 //only with 'SkipOnuConfig' we need to wait for all finished-signals
1060 // from vlanConfig processing of all UNI's.
1061 logger.Debugw(ctx, "reconciling flows - waiting on ready indication of requested UNIs", log.Fields{
1062 "device-id": dh.DeviceID, "expiry": dh.reconcileExpiryVlanConfig})
1063 if executed := loWaitGroupWTO.WaitTimeout(dh.reconcileExpiryVlanConfig); executed {
1064 logger.Debugw(ctx, "reconciling flows for all UNI's has been finished in time",
1065 log.Fields{"device-id": dh.DeviceID})
1066 dh.stopReconciling(ctx, true, cWaitReconcileFlowAbortOnSuccess)
1067 if pDevEntry != nil {
1068 pDevEntry.SendChReconcilingFlowsFinished(true)
1069 }
1070 } else {
1071 logger.Errorw(ctx, "timeout waiting for reconciling flows for all UNI's to be finished!",
1072 log.Fields{"device-id": dh.DeviceID})
1073 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
1074 if pDevEntry != nil {
1075 pDevEntry.SendChReconcilingFlowsFinished(false)
1076 }
1077 return
1078 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001080 }
1081}
1082
mpagenko101ac942021-11-16 15:01:29 +00001083func (dh *deviceHandler) updateReconcileFlowConfig(ctx context.Context, apUniPort *cmn.OnuUniPort,
1084 aPersFlowParam []cmn.UniVlanFlowParams, aUniVlanConfigEntries []uint8,
1085 apWaitGroup *cmn.WaitGroupWithTimeOut, apFlowsFound *bool) {
1086 flowsProcessed := 0
1087 lastFlowToReconcile := false
1088 loUniID := apUniPort.UniID
1089 for _, flowData := range aPersFlowParam {
1090 if dh.IsSkipOnuConfigReconciling() {
1091 if !(*apFlowsFound) {
1092 *apFlowsFound = true
1093 syncChannel := make(chan struct{})
1094 // start go routine with select() on reconciling vlan config channel before
1095 // starting vlan config reconciling process to prevent loss of any signal
1096 // this routine just collects all the received 'flow-reconciled' signals - possibly from different UNI's
1097 go dh.waitOnUniVlanConfigReconcilingReady(ctx, syncChannel, apWaitGroup)
1098 //block until the wait routine is really blocked on channel input
1099 // in order to prevent to early ready signal from VlanConfig processing
1100 <-syncChannel
1101 }
1102 if flowsProcessed == len(aPersFlowParam)-1 {
1103 var uniAdded bool
1104 lastFlowToReconcile = true
1105 if aUniVlanConfigEntries, uniAdded = dh.appendIfMissing(aUniVlanConfigEntries, loUniID); uniAdded {
1106 apWaitGroup.Add(1) //increment the waiting group
1107 }
1108 }
1109 }
1110 // note for above block: also lastFlowToReconcile (as parameter to flow config below)
1111 // is only relevant in the vlanConfig processing for IsSkipOnuConfigReconciling = true
1112 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1113 "device-id": dh.DeviceID, "uni-id": loUniID,
1114 "flowsProcessed": flowsProcessed, "cookies": flowData.CookieSlice})
1115 dh.lockVlanConfig.Lock()
1116 //the CookieSlice can be passed 'by value' here, - which internally passes its reference
1117 if _, exist := dh.UniVlanConfigFsmMap[loUniID]; exist {
1118 if err := dh.UniVlanConfigFsmMap[loUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
1119 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1120 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter, nil); err != nil {
1121 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1122 }
1123 } else {
1124 if err := dh.createVlanFilterFsm(ctx, apUniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
1125 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
1126 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter, nil); err != nil {
1127 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
1128 }
1129 }
1130 dh.lockVlanConfig.Unlock()
1131 flowsProcessed++
1132 } //for all flows of this UNI
1133}
1134
1135//waitOnUniVlanConfigReconcilingReady collects all VlanConfigReady signals from VlanConfig FSM processing in reconciling
1136// and decrements the according handler wait group waiting for these indications
1137func (dh *deviceHandler) waitOnUniVlanConfigReconcilingReady(ctx context.Context, aSyncChannel chan<- struct{},
1138 waitGroup *cmn.WaitGroupWithTimeOut) {
1139 var reconciledUniVlanConfigEntries []uint8
1140 var appended bool
1141 expiry := dh.GetReconcileExpiryVlanConfigAbort()
1142 logger.Debugw(ctx, "start waiting on reconcile vlanConfig ready indications", log.Fields{
1143 "device-id": dh.DeviceID, "expiry": expiry})
1144 // indicate blocking on channel now to the caller
1145 aSyncChannel <- struct{}{}
1146 for {
1147 select {
1148 case uniIndication := <-dh.chUniVlanConfigReconcilingDone:
1149 switch uniIndication {
1150 // no activity requested (should normally not be received) - just continue waiting
1151 case cWaitReconcileFlowNoActivity:
1152 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on error condition
1153 case cWaitReconcileFlowAbortOnError:
1154 logger.Debugw(ctx, "waitReconcileFlow aborted on error",
1155 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1156 return
1157 // waiting on channel inputs from VlanConfig for all UNI's to be aborted on success condition
1158 case cWaitReconcileFlowAbortOnSuccess:
1159 logger.Debugw(ctx, "waitReconcileFlow aborted on success",
1160 log.Fields{"device-id": dh.DeviceID, "rxEntries": reconciledUniVlanConfigEntries})
1161 return
1162 // this should be a valid UNI vlan config done indication
1163 default:
1164 if uniIndication < platform.MaxUnisPerOnu {
1165 logger.Debugw(ctx, "reconciling flows has been finished in time for this UNI",
1166 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1167 if reconciledUniVlanConfigEntries, appended =
1168 dh.appendIfMissing(reconciledUniVlanConfigEntries, uint8(uniIndication)); appended {
1169 waitGroup.Done()
1170 }
1171 } else {
1172 logger.Errorw(ctx, "received unexpected UNI flowConfig done indication - is ignored",
1173 log.Fields{"device-id": dh.DeviceID, "uni-id": uniIndication})
1174 }
1175 } //switch uniIndication
1176
1177 case <-time.After(expiry): //a bit longer than reconcileExpiryVlanConfig
1178 logger.Errorw(ctx, "timeout waiting for reconciling all UNI flows to be finished!",
1179 log.Fields{"device-id": dh.DeviceID})
1180 return
1181 }
1182 }
1183}
1184
1185func (dh *deviceHandler) GetReconcileExpiryVlanConfigAbort() time.Duration {
1186 return dh.reconcileExpiryVlanConfig + (500 * time.Millisecond)
1187}
1188
1189func (dh *deviceHandler) appendIfMissing(slice []uint8, val uint8) ([]uint8, bool) {
1190 for _, ele := range slice {
1191 if ele == val {
1192 return slice, false
1193 }
1194 }
1195 return append(slice, val), true
1196}
1197
1198// sendChReconcileFinished - sends true or false on reconcileFinish channel
1199func (dh *deviceHandler) sendChReconcileFinished(success bool) {
1200 if dh != nil { //if the object still exists (might have been already deleted in background)
1201 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1202 select {
1203 case dh.chReconcilingFinished <- success:
1204 default:
1205 }
1206 }
1207}
1208
1209// SendChUniVlanConfigFinished - sends the Uni number on channel if the flow reconcilement for this UNI is finished
1210func (dh *deviceHandler) SendChUniVlanConfigFinished(value uint16) {
1211 if dh != nil { //if the object still exists (might have been already deleted in background)
1212 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1213 select {
1214 case dh.chUniVlanConfigReconcilingDone <- value:
1215 default:
1216 }
1217 }
1218}
1219
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001220func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001222 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001223}
1224
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001227
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001229 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001230 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001231 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001232 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001233 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001234
1235 // deadline context to ensure completion of background routines waited for
1236 //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 +05301237 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001239
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001240 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001241
1242 var wg sync.WaitGroup
1243 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001246
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001247 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001248 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001249}
1250
mpagenko15ff4a52021-03-02 10:09:20 +00001251//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1252// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001253// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001254//was and is called in background - error return does not make sense
1255func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001256 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001257 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001259 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001260 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001261 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301262 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001264 return
Himani Chawla4d908332020-08-31 12:30:20 +05301265 }
mpagenko01e726e2020-10-23 09:45:29 +00001266
1267 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001269
mpagenko44bd8362021-11-15 11:40:05 +00001270 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
mpagenko44bd8362021-11-15 11:40:05 +00001272 // 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 -04001273 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00001275 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04001276 OperStatus: voltha.OperStatus_DISCOVERED,
1277 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001278 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001280 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001281 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001283 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001284 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001286 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1287 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1288 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1289 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001290}
1291
mpagenkoc8bba412021-01-15 15:38:44 +00001292//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001293// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001294func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001296 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001298
1299 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001300 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001301 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1303 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001304 }
1305
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001307 var inactiveImageID uint16
1308 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1309 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00001310 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1311 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001312 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001314 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001315 if err == nil {
1316 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1317 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001319 }
1320 } else {
1321 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001323 }
mpagenko15ff4a52021-03-02 10:09:20 +00001324 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko59862f02021-10-11 08:53:18 +00001325 dh.lockUpgradeFsm.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001326 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00001327 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1328 dh.upgradeCanceled = true
1329 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1330 }
mpagenko38662d02021-08-11 09:45:19 +00001331 //no effort spent anymore for the old API to automatically cancel and restart the download
1332 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001333 }
mpagenko15ff4a52021-03-02 10:09:20 +00001334 } else {
1335 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001337 }
1338 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1340 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001341 }
1342 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001343}
1344
mpagenkoc26d4c02021-05-06 14:27:57 +00001345//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1346// after the OnuImage has been downloaded to the adapter, called in background
1347func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001349
1350 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001352 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001353 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001354 return
1355 }
1356
1357 var inactiveImageID uint16
1358 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1359 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001361
mpagenko59862f02021-10-11 08:53:18 +00001362 dh.lockUpgradeFsm.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko59862f02021-10-11 08:53:18 +00001364 // but must be still locked at calling createOnuUpgradeFsm
1365 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1366 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1367 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001368 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1369 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001370 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001371 //flush the remove upgradeFsmChan channel
1372 select {
1373 case <-dh.upgradeFsmChan:
1374 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1375 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001376 }
mpagenko59862f02021-10-11 08:53:18 +00001377 dh.lockUpgradeFsm.Unlock()
1378 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1379 dh.upgradeCanceled = true
1380 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1381 }
mpagenko38662d02021-08-11 09:45:19 +00001382 select {
1383 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001384 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001385 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1386 return
1387 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001389 }
mpagenko59862f02021-10-11 08:53:18 +00001390 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001391 }
mpagenko38662d02021-08-11 09:45:19 +00001392
1393 //here it can be assumed that no running upgrade processing exists (anymore)
mpagenko59862f02021-10-11 08:53:18 +00001394 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
mpagenko38662d02021-08-11 09:45:19 +00001395 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001396 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko59862f02021-10-11 08:53:18 +00001397 dh.lockUpgradeFsm.Unlock()
mpagenko38662d02021-08-11 09:45:19 +00001398 if err == nil {
1399 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1400 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1401 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001403 return
1404 }
mpagenko38662d02021-08-11 09:45:19 +00001405 } else {
1406 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001408 }
1409 return
1410 }
1411 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001413}
1414
1415//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001416func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1417 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001418 var err error
1419 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1420 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1421 // 2.) activation of the inactive image
1422
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001424 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001425 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1426 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001427 }
1428 dh.lockUpgradeFsm.RLock()
1429 if dh.pOnuUpradeFsm != nil {
1430 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001433 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1434 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001435 }
mpagenko59862f02021-10-11 08:53:18 +00001436 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1437 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1438 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1439 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001440 // use the OnuVendor identification from this device for the internal unique name
1441 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001442 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001443 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001444 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001445 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001446 "device-id": dh.DeviceID, "error": err})
1447 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001448 }
mpagenko183647c2021-06-08 15:25:04 +00001449 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001450 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001451 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001452 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001453 } //else
1454 dh.lockUpgradeFsm.RUnlock()
1455
1456 // 2.) check if requested image-version equals the inactive one and start its activation
1457 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1458 var inactiveImageID uint16
1459 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1460 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001461 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1462 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001463 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001464 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001465 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001466 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001467 if err == nil {
1468 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1469 inactiveImageID, aCommitRequest); err != nil {
1470 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 "device-id": dh.DeviceID, "error": err})
1472 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001473 }
1474 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001475 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001476 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001477 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001478 } //else
1479 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001480 "device-id": dh.DeviceID, "error": err})
1481 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001482}
1483
1484//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001485func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1486 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001487 var err error
1488 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1489 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1490 // 2.) commitment of the active image
1491
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001492 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001493 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001494 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1495 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001496 }
1497 dh.lockUpgradeFsm.RLock()
1498 if dh.pOnuUpradeFsm != nil {
1499 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001501 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001502 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1503 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001504 }
mpagenko59862f02021-10-11 08:53:18 +00001505 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1506 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
1507 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.DeviceID)
1508 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001509 // use the OnuVendor identification from this device for the internal unique name
1510 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001511 // 1.) check a started upgrade process and relay the commitment request to it
1512 // the running upgrade may be based either on the imageIdentifier (started from download)
1513 // or on the imageVersion (started from pure activation)
1514 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1515 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001516 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 "device-id": dh.DeviceID, "error": err})
1518 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001519 }
mpagenko183647c2021-06-08 15:25:04 +00001520 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001522 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001523 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001524 } //else
1525 dh.lockUpgradeFsm.RUnlock()
1526
mpagenko183647c2021-06-08 15:25:04 +00001527 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001528 var activeImageID uint16
1529 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1530 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001531 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1532 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001533 }
mpagenkoa2b288f2021-10-21 11:25:27 +00001534 dh.lockUpgradeFsm.Lock() //lock again for following creation
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoa2b288f2021-10-21 11:25:27 +00001536 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001537 if err == nil {
1538 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1539 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001540 "device-id": dh.DeviceID, "error": err})
1541 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001542 }
1543 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001544 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001545 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001546 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001547 } //else
1548 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001549 "device-id": dh.DeviceID, "error": err})
1550 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001551}
1552
mpagenkoaa3afe92021-05-21 16:20:58 +00001553func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001554 aVersion string) *voltha.ImageState {
1555 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001556 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001557 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001558 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001559 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1560 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1561 if aVersion == dh.pLastUpgradeImageState.Version {
1562 pImageState = dh.pLastUpgradeImageState
1563 } else { //state request for an image version different from last processed image version
1564 pImageState = &voltha.ImageState{
1565 Version: aVersion,
1566 //we cannot state something concerning this version
1567 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1568 Reason: voltha.ImageState_NO_ERROR,
1569 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1570 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001571 }
1572 }
mpagenko38662d02021-08-11 09:45:19 +00001573 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001574}
1575
1576func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1577 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001578 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001579 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001580 dh.lockUpgradeFsm.RLock()
1581 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001582 dh.lockUpgradeFsm.RUnlock()
1583 // so then we cancel the upgrade operation
mpagenkoa2b288f2021-10-21 11:25:27 +00001584 // but before we still request the actual upgrade states for the direct response
mpagenko45586762021-10-01 08:30:22 +00001585 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1586 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1587 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1588 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1589 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1590 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00001591 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1592 dh.upgradeCanceled = true
1593 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1594 }
mpagenko45586762021-10-01 08:30:22 +00001595 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001596 } else {
mpagenko45586762021-10-01 08:30:22 +00001597 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001598 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1599 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1600 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1601 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1602 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1603 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001604 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1605 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001606 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1607 //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 +00001608 }
1609}
1610
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001611func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1612
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001614
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001616 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1618 pDevEntry.MutexOnuImageStatus.Lock()
1619 pDevEntry.POnuImageStatus = onuImageStatus
1620 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001621
1622 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001624 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1625 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001626 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1627 pDevEntry.MutexOnuImageStatus.Lock()
1628 pDevEntry.POnuImageStatus = nil
1629 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001630 return images, err
1631}
1632
Himani Chawla6d2ae152020-09-02 13:11:20 +05301633// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634// #####################################################################################
1635
1636// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301637// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001638
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 logger.Debugw(ctx, "Device FSM: ", log.Fields{"event name": string(e.Event), "src state": string(e.Src), "dst state": string(e.Dst), "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001641}
1642
1643// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001645
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001647 var err error
1648
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001649 // populate what we know. rest comes later after mib sync
1650 dh.device.Root = false
1651 dh.device.Vendor = "OpenONU"
1652 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001653 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1654 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001657
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001658 if !dh.IsReconciling() {
1659 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001660 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1661 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1662 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301663 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001664 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001667 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668
Himani Chawla4d908332020-08-31 12:30:20 +05301669 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001670 dh.ponPortNumber = dh.device.ParentPortNo
1671
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1673 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1674 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001676 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301677 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001678
1679 /*
1680 self._pon = PonPort.create(self, self._pon_port_number)
1681 self._pon.add_peer(self.parent_id, self._pon_port_number)
1682 self.logger.debug('adding-pon-port-to-agent',
1683 type=self._pon.get_port().type,
1684 admin_state=self._pon.get_port().admin_state,
1685 oper_status=self._pon.get_port().oper_status,
1686 )
1687 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 if !dh.IsReconciling() {
1689 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001690 var ponPortNo uint32 = 1
1691 if dh.ponPortNumber != 0 {
1692 ponPortNo = dh.ponPortNumber
1693 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001694
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001695 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001696 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001697 PortNo: ponPortNo,
1698 Label: fmt.Sprintf("pon-%d", ponPortNo),
1699 Type: voltha.Port_PON_ONU,
1700 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301701 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001702 PortNo: ponPortNo}}, // Peer port is parent's port number
1703 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001704 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001706 e.Cancel(err)
1707 return
1708 }
1709 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001710 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001711 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001713}
1714
1715// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001717
dbainbri4d3a0dc2020-12-02 00:33:42 +00001718 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 var err error
1720 /*
1721 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1722 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1723 return nil
1724 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1726 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001727 e.Cancel(err)
1728 return
1729 }
1730
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001731 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001733 // reconcilement will be continued after mib download is done
1734 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001735
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001736 /*
1737 ############################################################################
1738 # Setup Alarm handler
1739 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1740 device.serial_number)
1741 ############################################################################
1742 # Setup PM configuration for this device
1743 # Pass in ONU specific options
1744 kwargs = {
1745 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1746 'heartbeat': self.heartbeat,
1747 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1748 }
1749 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1750 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1751 self.logical_device_id, device.serial_number,
1752 grouped=True, freq_override=False, **kwargs)
1753 pm_config = self._pm_metrics.make_proto()
1754 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1755 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1756 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1757
1758 # Note, ONU ID and UNI intf set in add_uni_port method
1759 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1760 ani_ports=[self._pon])
1761
1762 # Code to Run OMCI Test Action
1763 kwargs_omci_test_action = {
1764 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1765 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1766 }
1767 serial_number = device.serial_number
1768 self._test_request = OmciTestRequest(self.core_proxy,
1769 self.omci_agent, self.device_id,
1770 AniG, serial_number,
1771 self.logical_device_id,
1772 exclusive=False,
1773 **kwargs_omci_test_action)
1774
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001775 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001776 else:
1777 self.logger.info('onu-already-activated')
1778 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001779
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001781}
1782
1783// doStateConnected get the device info and update to voltha core
1784// for comparison of the original method (not that easy to uncomment): compare here:
1785// voltha-openolt-adapter/adaptercore/device_handler.go
1786// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001788
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301790 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001792 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001793}
1794
1795// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301799 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802
1803 /*
1804 // Synchronous call to update device state - this method is run in its own go routine
1805 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1806 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001807 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 +00001808 return err
1809 }
1810 return nil
1811 */
1812}
1813
1814// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001816
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001818 var err error
1819
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001820 device := dh.device
1821 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001822 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001823 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001824 e.Cancel(err)
1825 return
1826 }
1827
1828 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001830 /*
1831 // Update the all ports state on that device to disable
1832 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001833 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 return er
1835 }
1836
1837 //Update the device oper state and connection status
1838 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1839 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1840 dh.device = cloned
1841
1842 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001843 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001844 return er
1845 }
1846
1847 //get the child device for the parent device
1848 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1849 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001850 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001851 return err
1852 }
1853 for _, onuDevice := range onuDevices.Items {
1854
1855 // Update onu state as down in onu adapter
1856 onuInd := oop.OnuIndication{}
1857 onuInd.OperState = "down"
khenaidoo42dcdfd2021-10-19 17:34:12 -04001858 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ca.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001859 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1860 if er != nil {
1861 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001862 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001863 //Do not return here and continue to process other ONUs
1864 }
1865 }
1866 // * Discovered ONUs entries need to be cleared , since after OLT
1867 // is up, it starts sending discovery indications again* /
1868 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001869 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001870 return nil
1871 */
Himani Chawla4d908332020-08-31 12:30:20 +05301872 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001873 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001875}
1876
Himani Chawla6d2ae152020-09-02 13:11:20 +05301877// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001878// #################################################################################
1879
1880// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301881// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001882
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001883//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1884func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001885 dh.lockDevice.RLock()
1886 pOnuDeviceEntry := dh.pOnuOmciDevice
1887 if aWait && pOnuDeviceEntry == nil {
1888 //keep the read sema short to allow for subsequent write
1889 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001890 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001891 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1892 // so it might be needed to wait here for that event with some timeout
1893 select {
1894 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001895 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001896 return nil
1897 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001898 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001899 // if written now, we can return the written value without sema
1900 return dh.pOnuOmciDevice
1901 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902 }
mpagenko3af1f032020-06-10 08:53:41 +00001903 dh.lockDevice.RUnlock()
1904 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001905}
1906
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001907//setDeviceHandlerEntries sets the ONU device entry within the handler
1908func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1909 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001910 dh.lockDevice.Lock()
1911 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001912 dh.pOnuOmciDevice = apDeviceEntry
1913 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001914 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301915 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001916 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001917}
1918
Himani Chawla6d2ae152020-09-02 13:11:20 +05301919//addOnuDeviceEntry creates a new ONU device or returns the existing
1920func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001921 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001922
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001923 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001924 if deviceEntry == nil {
1925 /* costum_me_map in python code seems always to be None,
1926 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1927 /* also no 'clock' argument - usage open ...*/
1928 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001929 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1930 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1931 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1932 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1933 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001934 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001935 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001936 // fire deviceEntry ready event to spread to possibly waiting processing
1937 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001938 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001939 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001940 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001941 }
1942 // might be updated with some error handling !!!
1943 return nil
1944}
1945
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1947 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001948 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1949
1950 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001951
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001953 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001954 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1955 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001956 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001957 if !dh.IsReconciling() {
1958 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001961 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001963 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001964
khenaidoo42dcdfd2021-10-19 17:34:12 -04001965 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001966 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001967 OperStatus: voltha.OperStatus_ACTIVATING,
1968 ConnStatus: voltha.ConnectStatus_REACHABLE,
1969 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001970 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001972 }
1973 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001976
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001977 pDevEntry.MutexPersOnuConfig.RLock()
1978 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1979 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 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 +00001981 log.Fields{"device-id": dh.DeviceID})
mpagenko101ac942021-11-16 15:01:29 +00001982 dh.stopReconciling(ctx, true, cWaitReconcileFlowNoActivity)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001983 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001984 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001985 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001986 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001987 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1988 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1989 // 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 +00001990 // 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 +00001991 // so let's just try to keep it simple ...
1992 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001994 if err != nil || device == nil {
1995 //TODO: needs to handle error scenarios
1996 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1997 return errors.New("Voltha Device not found")
1998 }
1999 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002000
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002001 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002002 return err
mpagenko3af1f032020-06-10 08:53:41 +00002003 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002004
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002005 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002006
2007 /* this might be a good time for Omci Verify message? */
2008 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002009 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00002010 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00002011 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002012 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002013
2014 /* give the handler some time here to wait for the OMCi verification result
2015 after Timeout start and try MibUpload FSM anyway
2016 (to prevent stopping on just not supported OMCI verification from ONU) */
2017 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002018 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002020 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002022 }
2023
2024 /* In py code it looks earlier (on activate ..)
2025 # Code to Run OMCI Test Action
2026 kwargs_omci_test_action = {
2027 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
2028 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
2029 }
2030 serial_number = device.serial_number
2031 self._test_request = OmciTestRequest(self.core_proxy,
2032 self.omci_agent, self.device_id,
2033 AniG, serial_number,
2034 self.logical_device_id,
2035 exclusive=False,
2036 **kwargs_omci_test_action)
2037 ...
2038 # Start test requests after a brief pause
2039 if not self._test_request_started:
2040 self._test_request_started = True
2041 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
2042 reactor.callLater(tststart, self._test_request.start_collector)
2043
2044 */
2045 /* which is then: in omci_test_request.py : */
2046 /*
2047 def start_collector(self, callback=None):
2048 """
2049 Start the collection loop for an adapter if the frequency > 0
2050
2051 :param callback: (callable) Function to call to collect PM data
2052 """
2053 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
2054 if callback is None:
2055 callback = self.perform_test_omci
2056
2057 if self.lc is None:
2058 self.lc = LoopingCall(callback)
2059
2060 if self.default_freq > 0:
2061 self.lc.start(interval=self.default_freq / 10)
2062
2063 def perform_test_omci(self):
2064 """
2065 Perform the initial test request
2066 """
2067 ani_g_entities = self._device.configuration.ani_g_entities
2068 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
2069 is not None else None
2070 self._entity_id = ani_g_entities_ids[0]
2071 self.logger.info('perform-test', entity_class=self._entity_class,
2072 entity_id=self._entity_id)
2073 try:
2074 frame = MEFrame(self._entity_class, self._entity_id, []).test()
2075 result = yield self._device.omci_cc.send(frame)
2076 if not result.fields['omci_message'].fields['success_code']:
2077 self.logger.info('Self-Test Submitted Successfully',
2078 code=result.fields[
2079 'omci_message'].fields['success_code'])
2080 else:
2081 raise TestFailure('Test Failure: {}'.format(
2082 result.fields['omci_message'].fields['success_code']))
2083 except TimeoutError as e:
2084 self.deferred.errback(failure.Failure(e))
2085
2086 except Exception as e:
2087 self.logger.exception('perform-test-Error', e=e,
2088 class_id=self._entity_class,
2089 entity_id=self._entity_id)
2090 self.deferred.errback(failure.Failure(e))
2091
2092 */
2093
2094 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002095 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002096
mpagenko1cc3cb42020-07-27 15:24:38 +00002097 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
2098 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
2099 * 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 +05302100 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00002101 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002102 //call MibUploadFSM - transition up to state UlStInSync
2103 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002104 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002105 if pMibUlFsm.Is(mib.UlStDisabled) {
2106 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
2107 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
2108 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302109 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002110 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05302111 //Determine ONU status and start/re-start MIB Synchronization tasks
2112 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002113 if pDevEntry.IsNewOnu() {
2114 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
2115 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
2116 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002117 }
Himani Chawla4d908332020-08-31 12:30:20 +05302118 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002119 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
2120 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
2121 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05302122 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002124 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00002125 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002127 "device-id": dh.DeviceID})
2128 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002129 }
2130 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002131 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
2132 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002133 }
2134 return nil
2135}
2136
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002138 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002139 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
2141 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002142
mpagenko900ee4b2020-10-12 11:56:34 +00002143 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2144 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2145 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002146 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002148 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002149 // abort: system behavior is just unstable ...
2150 return err
2151 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002152 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002153 _ = 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 +00002154
2155 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
mpagenko44bd8362021-11-15 11:40:05 +00002156 //stop the device entry to allow for all system event transfers again
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002157 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002158 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2160 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002161 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002162 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002163
2164 //TODO!!! remove existing traffic profiles
2165 /* from py code, if TP's exist, remove them - not yet implemented
2166 self._tp = dict()
2167 # Let TP download happen again
2168 for uni_id in self._tp_service_specific_task:
2169 self._tp_service_specific_task[uni_id].clear()
2170 for uni_id in self._tech_profile_download_done:
2171 self._tech_profile_download_done[uni_id].clear()
2172 */
2173
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002174 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002175
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002176 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002177
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002178 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002179 // abort: system behavior is just unstable ...
2180 return err
2181 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002182 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002183 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002184 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002186 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
2187 OperStatus: voltha.OperStatus_DISCOVERED,
2188 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002189 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002192 // abort: system behavior is just unstable ...
2193 return err
2194 }
2195 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002197 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002198 return nil
2199}
2200
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002201func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002202 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2203 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2204 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2205 // and using the stop/reset event should never harm
2206
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002208 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
2210 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00002211 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002212 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002213 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002214 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 pDevEntry.MutexOnuImageStatus.RLock()
2216 if pDevEntry.POnuImageStatus != nil {
2217 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002218 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002219 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002220
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002221 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002222 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002223 }
2224 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00002226 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002227 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002228 }
mpagenko101ac942021-11-16 15:01:29 +00002229 //stop any deviceHandler reconcile processing (if running)
2230 dh.stopReconciling(ctx, false, cWaitReconcileFlowAbortOnError)
mpagenko900ee4b2020-10-12 11:56:34 +00002231 //port lock/unlock FSM's may be active
2232 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002233 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002234 }
2235 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00002237 }
2238 //techProfile related PonAniConfigFsm FSM may be active
2239 if dh.pOnuTP != nil {
2240 // should always be the case here
2241 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 if dh.pOnuTP.PAniConfigFsm != nil {
2243 for uniTP := range dh.pOnuTP.PAniConfigFsm {
2244 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002245 }
mpagenko900ee4b2020-10-12 11:56:34 +00002246 }
2247 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002248 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002249 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00002251 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002252 dh.lockVlanConfig.RUnlock()
mpagenko7d6bb022021-03-11 15:07:55 +00002253 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002254 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002255 } else {
2256 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002257 }
2258 }
2259 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002260 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002261 // Stop collector routine
2262 dh.stopCollector <- true
2263 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302265 dh.stopAlarmManager <- true
2266 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002267 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002268 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002269 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302270
Girish Gowdrae95687a2021-09-08 16:30:58 -07002271 // Note: We want flow deletes to be processed on onu down, so do not stop flow monitoring routines
2272
mpagenko80622a52021-02-09 16:53:23 +00002273 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002274 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002275 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002276 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002277 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002278 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002279 if lopOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00002280 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2281 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2282 // (even though it may also run into direct cancellation, a bit hard to verify here)
2283 // so don't set 'dh.upgradeCanceled = true' here!
2284 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2285 }
mpagenko38662d02021-08-11 09:45:19 +00002286 }
mpagenko80622a52021-02-09 16:53:23 +00002287
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002289 return nil
2290}
2291
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002292func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2293 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 +05302294
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002295 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002297 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002298 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002299 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002300 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2301 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002302
mpagenkoa40e99a2020-11-17 13:50:39 +00002303 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2304 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2305 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2306 * disable/enable toggling here to allow traffic
2307 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2308 * like the py comment says:
2309 * # start by locking all the unis till mib sync and initial mib is downloaded
2310 * # this way we can capture the port down/up events when we are ready
2311 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302312
mpagenkoa40e99a2020-11-17 13:50:39 +00002313 // Init Uni Ports to Admin locked state
2314 // *** should generate UniLockStateDone event *****
2315 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002316 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002317 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002320 }
2321}
2322
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002323func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2324 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302325 /* Mib download procedure -
2326 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2327 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002328 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002329 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002331 return
2332 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002333 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302334 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002335 if pMibDlFsm.Is(mib.DlStDisabled) {
2336 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2337 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 +05302338 // maybe try a FSM reset and then again ... - TODO!!!
2339 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302341 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002342 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2343 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302344 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002345 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302346 //Begin MIB data download (running autonomously)
2347 }
2348 }
2349 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002350 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002351 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302352 // maybe try a FSM reset and then again ... - TODO!!!
2353 }
2354 /***** Mib download started */
2355 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002356 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302357 }
2358}
2359
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002360func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2361 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302362 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002366 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2367 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2368 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2369 dh.checkOnOnuImageCommit(ctx)
khenaidoo42dcdfd2021-10-19 17:34:12 -04002370 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002371 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002372 ConnStatus: voltha.ConnectStatus_REACHABLE,
2373 OperStatus: voltha.OperStatus_ACTIVE,
2374 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302375 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302377 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302379 }
2380 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002382 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302383 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002384 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002385
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002387 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002389 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002390 if !dh.GetAlarmManagerIsRunning(ctx) {
2391 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002392 }
2393
Girish Gowdrae95687a2021-09-08 16:30:58 -07002394 // Start flow handler routines per UNI
2395 for _, uniPort := range dh.uniEntityMap {
2396 // only if this port was enabled for use by the operator at startup
2397 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2398 if !dh.GetFlowMonitoringIsRunning(uniPort.UniID) {
2399 go dh.PerOnuFlowHandlerRoutine(uniPort.UniID)
2400 }
2401 }
2402 }
2403
Girish Gowdrae0140f02021-02-02 16:55:09 -08002404 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002405 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002406 // There is no way we should be landing here, but if we do then
2407 // there is nothing much we can do about this other than log error
2408 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2409 }
2410
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002412
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002413 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002414 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002415 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002416 return
2417 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002418 pDevEntry.MutexPersOnuConfig.RLock()
2419 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2420 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002421 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002422 log.Fields{"device-id": dh.DeviceID})
2423 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002424 // reconcilement will be continued after ani config is done
2425 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002426 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002427 // *** should generate UniUnlockStateDone event *****
2428 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002429 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002430 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002431 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002432 dh.runUniLockFsm(ctx, false)
2433 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302434 }
2435}
2436
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002437func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2438 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302439
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002440 if !dh.IsReconciling() {
2441 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002442 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002443 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2444 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002445 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002447 return
2448 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002449 pDevEntry.MutexPersOnuConfig.Lock()
2450 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2451 pDevEntry.MutexPersOnuConfig.Unlock()
2452 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002455 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302456 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 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 +00002458 log.Fields{"device-id": dh.DeviceID})
2459 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002460 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302461 }
2462}
2463
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002464func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
mpagenko44bd8362021-11-15 11:40:05 +00002465 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002467
mpagenko44bd8362021-11-15 11:40:05 +00002468 // disable device should have no impact on ConnStatus
khenaidoo42dcdfd2021-10-19 17:34:12 -04002469 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002471 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
khenaidoo7d3c5582021-08-11 18:09:44 -04002472 OperStatus: voltha.OperStatus_UNKNOWN,
2473 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002474 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002476 }
2477
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002478 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002479 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002480 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002481
2482 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002483 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002484
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002486 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002488 return
2489 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002490 pDevEntry.MutexPersOnuConfig.Lock()
2491 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2492 pDevEntry.MutexPersOnuConfig.Unlock()
2493 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002496 }
mpagenko900ee4b2020-10-12 11:56:34 +00002497}
2498
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002499func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002501 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002502 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002504 ConnStatus: voltha.ConnectStatus_REACHABLE,
2505 OperStatus: voltha.OperStatus_ACTIVE,
2506 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002507 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002508 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002509 }
2510
dbainbri4d3a0dc2020-12-02 00:33:42 +00002511 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002512 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002513 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002514 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002515
2516 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002517 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002519 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002520 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002522 return
2523 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 pDevEntry.MutexPersOnuConfig.Lock()
2525 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2526 pDevEntry.MutexPersOnuConfig.Unlock()
2527 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002529 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002530 }
mpagenko900ee4b2020-10-12 11:56:34 +00002531}
2532
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002533func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2534 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2535 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04002536 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002537 DeviceId: dh.DeviceID,
mpagenko44bd8362021-11-15 11:40:05 +00002538 ConnStatus: connectStatusINVALID, //use some dummy value to prevent modification of the ConnStatus
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002539 OperStatus: voltha.OperStatus_FAILED,
2540 }); err != nil {
2541 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
2542 }
2543}
2544
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2546 if devEvent == cmn.OmciAniConfigDone {
2547 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002548 // attention: the device reason update is done based on ONU-UNI-Port related activity
2549 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002550 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002551 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302553 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002554 if dh.IsReconciling() {
2555 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002556 }
2557 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002559 // attention: the device reason update is done based on ONU-UNI-Port related activity
2560 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002562 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002563 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002564 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002565 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302566}
2567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002568func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302571 // attention: the device reason update is done based on ONU-UNI-Port related activity
2572 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302573
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002574 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2575 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002576 // which may be the case from some previous actvity on another UNI Port of the ONU
2577 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002578 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2579 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002580 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002581 }
2582 }
2583 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002585 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002586 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002587 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302588 }
mpagenkof1fc3862021-02-16 10:09:52 +00002589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002591 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002592 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002593 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002594 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002595 }
2596 } else {
2597 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002598 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002599 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302600}
2601
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002602//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2603func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302604 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002605 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002606 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002608 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002610 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002612 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002613 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002614 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002615 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002616 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002618 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002619 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002620 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002622 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002624 }
Mahir Gunyel50ddea62021-10-22 11:26:42 -07002625 case cmn.UniEnableStateFailed:
2626 {
2627 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2628 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002630 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002631 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002632 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002633 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002634 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002635 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002636 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002637 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002638 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002639 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002640 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002641 default:
2642 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002644 }
2645 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002646}
2647
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002648func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002649 // parameters are IntfId, OnuId, uniId
Mahir Gunyelcb128ae2021-10-06 09:42:05 -07002650 uniNo := platform.MkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302651 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002652 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002653 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002654 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302655 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002657 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002658 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002659 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002660 //store UniPort with the System-PortNumber key
2661 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002663 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002664 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2665 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002666 } //error logging already within UniPort method
2667 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002669 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002670 }
2671 }
2672}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002673
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002674func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2675 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002676 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002677 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002678 return
2679 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002680 uniCnt := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002681 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002682 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2683 for _, mgmtEntityID := range pptpInstKeys {
2684 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002686 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTP)
2687 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002688 }
2689 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002691 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002692 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002693 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2694 for _, mgmtEntityID := range veipInstKeys {
2695 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002696 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002697 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniVEIP)
2698 uniCnt++
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002699 }
2700 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002701 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002702 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002704 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2705 for _, mgmtEntityID := range potsInstKeys {
2706 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002708 dh.addUniPort(ctx, mgmtEntityID, uniCnt, cmn.UniPPTPPots)
2709 uniCnt++
ozgecanetsia124d9732021-09-16 14:31:57 +03002710 }
2711 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002712 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002713 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07002714 if uniCnt == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07002716 return
2717 }
2718
mpagenko2c3f6c52021-11-23 11:22:10 +00002719 //Note: For the moment is is not required to include the (newly added) POTS ports into the range
2720 // of flowCall or reconcile channels. But some sort of flow and reconcile processing might get necessary
2721 // 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 -07002722 dh.flowCbChan = make([]chan FlowCb, uniCnt)
2723 dh.stopFlowMonitoringRoutine = make([]chan bool, uniCnt)
2724 dh.isFlowMonitoringRoutineActive = make([]bool, uniCnt)
mpagenko2c3f6c52021-11-23 11:22:10 +00002725 //chUniVlanConfigReconcilingDone needs to have the capacity of all UniPorts as flow reconcile may run parallel for all of them
2726 dh.chUniVlanConfigReconcilingDone = make(chan uint16, uniCnt)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002727 for i := 0; i < int(uniCnt); i++ {
2728 dh.flowCbChan[i] = make(chan FlowCb, dh.pOpenOnuAc.config.MaxConcurrentFlowsPerUni)
2729 dh.stopFlowMonitoringRoutine[i] = make(chan bool)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002730 }
2731}
2732
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2734func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002735 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302736 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002737 // with following remark:
2738 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2739 // # load on the core
2740
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002741 // 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 +00002742
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002743 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002744 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2746 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2747 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2748 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002749 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002751 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002753 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754 PortNo: port.PortNo,
2755 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002756 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 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 -04002758 }
2759 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002760 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002761 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002762 }
mpagenko3af1f032020-06-10 08:53:41 +00002763 }
2764 }
2765}
2766
2767// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002768func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2769 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002770 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2771 for uniNo, uniPort := range dh.uniEntityMap {
2772 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002773
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2775 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2776 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2777 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002778 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002779 go func(port *cmn.OnuUniPort) {
khenaidoo42dcdfd2021-10-19 17:34:12 -04002780 if err := dh.updatePortStateInCore(ctx, &ca.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002782 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002783 PortNo: port.PortNo,
2784 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002785 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786 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 -04002787 }
2788 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002789 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002791 }
2792
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002793 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002794 }
2795}
2796
2797// ONU_Active/Inactive announcement on system KAFKA bus
2798// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002799func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002800 var de voltha.DeviceEvent
2801 eventContext := make(map[string]string)
2802 //Populating event context
2803 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002804 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002805 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002806 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302807 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002808 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 +00002809 }
2810 oltSerialNumber := parentDevice.SerialNumber
2811
2812 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2813 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2814 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302815 eventContext["olt-serial-number"] = oltSerialNumber
2816 eventContext["device-id"] = aDeviceID
2817 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002818 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2820 deviceEntry.MutexPersOnuConfig.RLock()
2821 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2822 deviceEntry.MutexPersOnuConfig.RUnlock()
2823 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2824 deviceEntry.MutexPersOnuConfig.RLock()
2825 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2826 deviceEntry.MutexPersOnuConfig.RUnlock()
2827 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002828 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2829 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2830 } else {
2831 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2832 log.Fields{"device-id": aDeviceID})
2833 return
2834 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002835
2836 /* Populating device event body */
2837 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302838 de.ResourceId = aDeviceID
2839 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002840 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2841 de.Description = fmt.Sprintf("%s Event - %s - %s",
2842 cEventObjectType, cOnuActivatedEvent, "Raised")
2843 } else {
2844 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2845 de.Description = fmt.Sprintf("%s Event - %s - %s",
2846 cEventObjectType, cOnuActivatedEvent, "Cleared")
2847 }
2848 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002849 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2850 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302851 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002852 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002853 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302854 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002855}
2856
Himani Chawla4d908332020-08-31 12:30:20 +05302857// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2859 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002860 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302861 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002862 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002863 sFsmName = "LockStateFSM"
2864 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002865 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002866 sFsmName = "UnLockStateFSM"
2867 }
mpagenko3af1f032020-06-10 08:53:41 +00002868
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002870 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002872 return
2873 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002874 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002875 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302876 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002877 dh.pLockStateFsm = pLSFsm
2878 } else {
2879 dh.pUnlockStateFsm = pLSFsm
2880 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002882 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002883 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002884 }
2885}
2886
2887// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002889 /* Uni Port lock/unlock procedure -
2890 ***** should run via 'adminDone' state and generate the argument requested event *****
2891 */
2892 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302893 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002894 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002895 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2896 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2898 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002899 }
2900 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002901 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002902 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2903 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002904 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2905 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002906 }
2907 }
2908 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002909 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2910 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002911 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002912 // maybe try a FSM reset and then again ... - TODO!!!
2913 } else {
2914 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002917 }
2918 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002919 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002921 // maybe try a FSM reset and then again ... - TODO!!!
2922 }
2923 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002925 // maybe try a FSM reset and then again ... - TODO!!!
2926 }
2927}
2928
mpagenko80622a52021-02-09 16:53:23 +00002929// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko59862f02021-10-11 08:53:18 +00002930// precondition: lockUpgradeFsm is already locked from caller of this function
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002933 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002934 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002935 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002937 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002938 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002940 sFsmName, chUpgradeFsm)
2941 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002943 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2945 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002946 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2947 // maybe try a FSM reset and then again ... - TODO!!!
2948 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2949 }
mpagenko59862f02021-10-11 08:53:18 +00002950 /***** Upgrade FSM started */
mpagenko45586762021-10-01 08:30:22 +00002951 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2952 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002953 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2954 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002955 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002957 } else {
2958 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002959 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
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, wrong internal state", dh.device.Id))
2962 }
2963 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002965 // maybe try a FSM reset and then again ... - TODO!!!
2966 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2967 }
2968 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002970 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2971 }
2972 return nil
2973}
2974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2976func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002977 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002978 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002979 dh.lockUpgradeFsm.Lock()
mpagenko59862f02021-10-11 08:53:18 +00002980 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2981 dh.upgradeCanceled = false //cancelation done
mpagenko38662d02021-08-11 09:45:19 +00002982 dh.pLastUpgradeImageState = apImageState
2983 dh.lockUpgradeFsm.Unlock()
2984 //signal upgradeFsm removed using non-blocking channel send
2985 select {
2986 case dh.upgradeFsmChan <- struct{}{}:
2987 default:
2988 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002990 }
mpagenko80622a52021-02-09 16:53:23 +00002991}
2992
mpagenko15ff4a52021-03-02 10:09:20 +00002993// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2994func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002995 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002996 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002997 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002998 return
2999 }
3000
3001 dh.lockUpgradeFsm.RLock()
mpagenko59862f02021-10-11 08:53:18 +00003002 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00003003 if dh.pOnuUpradeFsm != nil {
mpagenko59862f02021-10-11 08:53:18 +00003004 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
3005 dh.lockUpgradeFsm.RUnlock()
3006 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.DeviceID})
3007 return
3008 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00003010 if pUpgradeStatemachine != nil {
3011 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
3012 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 UpgradeState := pUpgradeStatemachine.Current()
3014 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
3015 (UpgradeState == swupg.UpgradeStRequestingActivate) {
3016 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00003017 // 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 +00003018 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00003019 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
3020 if errImg != nil {
mpagenko59862f02021-10-11 08:53:18 +00003021 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00003022 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003023 log.Fields{"device-id": dh.DeviceID})
mpagenko59862f02021-10-11 08:53:18 +00003024 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3025 dh.upgradeCanceled = true
3026 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3027 }
mpagenko15ff4a52021-03-02 10:09:20 +00003028 return
3029 }
mpagenko59862f02021-10-11 08:53:18 +00003030 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
3032 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00003033 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003035 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
3036 return
3037 }
3038 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003039 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003040 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
3042 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00003043 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
3044 return
3045 }
3046 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00003048 }
3049 } else {
3050 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 +00003051 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003052 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3053 dh.upgradeCanceled = true
3054 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3055 }
mpagenko1f8e8822021-06-25 14:10:21 +00003056 }
mpagenko15ff4a52021-03-02 10:09:20 +00003057 return
3058 }
mpagenko59862f02021-10-11 08:53:18 +00003059 dh.lockUpgradeFsm.RUnlock()
3060 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
3061 log.Fields{"device-id": dh.DeviceID})
mpagenkoa2b288f2021-10-21 11:25:27 +00003062 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
3063 dh.upgradeCanceled = true
3064 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
3065 }
mpagenko59862f02021-10-11 08:53:18 +00003066 return
3067 }
3068 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
3069 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
3070 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
3071 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
3072 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
3073 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
3074 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00003075 }
mpagenko15ff4a52021-03-02 10:09:20 +00003076 }
3077 }
3078 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003079 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00003080 }
mpagenko59862f02021-10-11 08:53:18 +00003081 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00003082}
3083
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084//SetBackend provides a DB backend for the specified path on the existing KV client
3085func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003086
3087 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003088 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07003089 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00003090 kvbackend := &db.Backend{
3091 Client: dh.pOpenOnuAc.kvClient,
3092 StoreType: dh.pOpenOnuAc.KVStoreType,
3093 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08003094 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00003095 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
3096 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00003097
mpagenkoaf801632020-07-03 10:00:42 +00003098 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00003099}
khenaidoo7d3c5582021-08-11 18:09:44 -04003100func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05303101 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00003102
mpagenkodff5dda2020-08-28 11:52:01 +00003103 for _, field := range flow.GetOfbFields(apFlowItem) {
3104 switch field.Type {
3105 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
3106 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003107 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003108 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
3109 }
mpagenko01e726e2020-10-23 09:45:29 +00003110 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00003111 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
3112 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303113 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
3116 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00003117 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3118 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003119 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303121 return
mpagenkodff5dda2020-08-28 11:52:01 +00003122 }
3123 }
mpagenko01e726e2020-10-23 09:45:29 +00003124 */
mpagenkodff5dda2020-08-28 11:52:01 +00003125 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
3126 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303127 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00003128 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05303129 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00003130 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303131 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00003132 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003133 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303134 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
3136 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
3137 {
Himani Chawla26e555c2020-08-31 12:30:20 +05303138 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003139 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003140 "PCP": loAddPcp})
3141 }
3142 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
3143 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003144 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003145 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
3146 }
3147 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
3148 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003149 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003150 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
3151 }
3152 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
3153 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003154 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003155 "IPv4-DST": field.GetIpv4Dst()})
3156 }
3157 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
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 "IPv4-SRC": field.GetIpv4Src()})
3161 }
3162 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
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 "Metadata": field.GetTableMetadata()})
3166 }
3167 /*
3168 default:
3169 {
3170 //all other entires ignored
3171 }
3172 */
3173 }
3174 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05303175}
mpagenkodff5dda2020-08-28 11:52:01 +00003176
khenaidoo7d3c5582021-08-11 18:09:44 -04003177func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00003178 for _, action := range flow.GetActions(apFlowItem) {
3179 switch action.Type {
3180 /* not used:
3181 case of.OfpActionType_OFPAT_OUTPUT:
3182 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003183 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003184 "Output": action.GetOutput()})
3185 }
3186 */
3187 case of.OfpActionType_OFPAT_PUSH_VLAN:
3188 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003189 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003190 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
3191 }
3192 case of.OfpActionType_OFPAT_SET_FIELD:
3193 {
3194 pActionSetField := action.GetSetField()
3195 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003196 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003197 "OxcmClass": pActionSetField.Field.OxmClass})
3198 }
3199 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303200 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003201 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303202 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003203 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303204 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003205 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303206 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003207 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003208 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003209 "Type": pActionSetField.Field.GetOfbField().Type})
3210 }
3211 }
3212 /*
3213 default:
3214 {
3215 //all other entires ignored
3216 }
3217 */
3218 }
3219 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303220}
3221
3222//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003224 apFlowMetaData *of.FlowMetadata, respChan *chan error) {
Himani Chawla26e555c2020-08-31 12:30:20 +05303225 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3226 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3227 var loAddPcp, loSetPcp uint8
3228 var loIPProto uint32
3229 /* the TechProfileId is part of the flow Metadata - compare also comment within
3230 * OLT-Adapter:openolt_flowmgr.go
3231 * Metadata 8 bytes:
3232 * Most Significant 2 Bytes = Inner VLAN
3233 * Next 2 Bytes = Tech Profile ID(TPID)
3234 * Least Significant 4 Bytes = Port ID
3235 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3236 * subscriber related flows.
3237 */
3238
dbainbri4d3a0dc2020-12-02 00:33:42 +00003239 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303240 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003241 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003242 log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -07003243 *respChan <- fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303244 }
mpagenko551a4d42020-12-08 18:09:20 +00003245 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003246 loCookie := apFlowItem.GetCookie()
3247 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003248 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003249 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303250
dbainbri4d3a0dc2020-12-02 00:33:42 +00003251 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003252 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303253 if loIPProto == 2 {
3254 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3255 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003256 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003257 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303258 return nil
3259 }
mpagenko01e726e2020-10-23 09:45:29 +00003260 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003261 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003262
3263 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003264 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003265 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00003266 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3267 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3268 //TODO!!: Use DeviceId within the error response to rwCore
3269 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Girish Gowdrae95687a2021-09-08 16:30:58 -07003270 *respChan <- fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003271 }
3272 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003274 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3275 } else {
3276 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3277 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3278 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303279 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003280 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003281 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003282 }
mpagenko9a304ea2020-12-16 15:54:01 +00003283
khenaidoo42dcdfd2021-10-19 17:34:12 -04003284 var meter *of.OfpMeterConfig
ozgecanetsia82b91a62021-05-21 18:54:49 +03003285 if apFlowMetaData != nil {
3286 meter = apFlowMetaData.Meters[0]
3287 }
mpagenkobc4170a2021-08-17 16:42:10 +00003288 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3289 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3290 // when different rules are requested concurrently for the same uni
3291 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3292 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3293 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
3295 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003296 //SetUniFlowParams() may block on some rule that is suspended-to-add
3297 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Girish Gowdrae95687a2021-09-08 16:30:58 -07003298 // Also the error is returned to caller via response channel
3299 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
3300 loMatchVlan, loSetVlan, loSetPcp, false, meter, respChan)
mpagenkobc4170a2021-08-17 16:42:10 +00003301 dh.lockVlanConfig.RUnlock()
3302 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003303 return
mpagenkodff5dda2020-08-28 11:52:01 +00003304 }
mpagenkobc4170a2021-08-17 16:42:10 +00003305 dh.lockVlanConfig.RUnlock()
3306 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003307 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003308 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter, respChan)
mpagenko7d14de12021-07-27 08:31:56 +00003309 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003310 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
Girish Gowdrae95687a2021-09-08 16:30:58 -07003311 if err != nil {
3312 *respChan <- err
3313 }
mpagenko01e726e2020-10-23 09:45:29 +00003314}
3315
3316//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Girish Gowdrae95687a2021-09-08 16:30:58 -07003317func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort, respChan *chan error) {
mpagenko01e726e2020-10-23 09:45:29 +00003318 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3319 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3320 //no extra check is done on the rule parameters
3321 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3322 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3323 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3324 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003325 // - 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 +00003326 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003327 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003328
3329 /* TT related temporary workaround - should not be needed anymore
3330 for _, field := range flow.GetOfbFields(apFlowItem) {
3331 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3332 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003333 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003334 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3335 if loIPProto == 2 {
3336 // 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 +00003337 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003338 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003339 return nil
3340 }
3341 }
3342 } //for all OfbFields
3343 */
3344
mpagenko9a304ea2020-12-16 15:54:01 +00003345 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003346 dh.lockVlanConfig.RLock()
3347 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003348 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3349 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003350 _ = dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie, respChan)
3351 return
mpagenko01e726e2020-10-23 09:45:29 +00003352 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003353 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003354 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003355 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003356 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Girish Gowdrae95687a2021-09-08 16:30:58 -07003357 // Push response on the response channel
3358 if respChan != nil {
3359 // 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
3360 select {
3361 case *respChan <- nil:
3362 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": dh.DeviceID, "err": nil})
3363 default:
3364 }
3365 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkodff5dda2020-08-28 11:52:01 +00003367}
3368
Himani Chawla26e555c2020-08-31 12:30:20 +05303369// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003370// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003371// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003372func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -04003373 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003375
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003376 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003377 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003378 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3379 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003380 }
3381
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003382 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3383 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Girish Gowdrae95687a2021-09-08 16:30:58 -07003384 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter, respChan)
mpagenkodff5dda2020-08-28 11:52:01 +00003385 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003386 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3387 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003388 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3389 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003390 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003391 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3392 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003393 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003395 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303396 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003397 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003398 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3399 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003400 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003401 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003402 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3403 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003404 }
3405 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003406 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003407 "device-id": dh.DeviceID})
3408 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003409 }
3410 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003411 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3413 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003414 }
3415 return nil
3416}
3417
mpagenkofc4f56e2020-11-04 17:17:49 +00003418//VerifyVlanConfigRequest checks on existence of a given uniPort
3419// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003420func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003421 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003422 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003423 for _, uniPort := range dh.uniEntityMap {
3424 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003425 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003426 pCurrentUniPort = uniPort
3427 break //found - end search loop
3428 }
3429 }
3430 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003431 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003432 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003433 return
3434 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003435 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003436}
3437
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003438//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3439func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003440 //TODO!! verify and start pending flow configuration
3441 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3442 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003443
3444 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003445 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003446 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003447 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003448 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003449 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003450 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003451 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003452 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3453 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003454 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003455 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003456 } else {
3457 /***** UniVlanConfigFsm continued */
3458 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3460 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003461 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003462 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3463 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003464 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003466 } else {
3467 /***** UniVlanConfigFsm continued */
3468 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3470 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003471 }
mpagenkodff5dda2020-08-28 11:52:01 +00003472 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003473 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003474 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3475 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003476 }
3477 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003478 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 +00003479 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3480 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003481 }
3482 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003483 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003484 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003485 }
mpagenkof1fc3862021-02-16 10:09:52 +00003486 } else {
3487 dh.lockVlanConfig.RUnlock()
3488 }
mpagenkodff5dda2020-08-28 11:52:01 +00003489}
3490
3491//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3492// 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 +00003493func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003494 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003495 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003496 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003497 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003498 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003499 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003500}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003501
mpagenkof1fc3862021-02-16 10:09:52 +00003502//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003503func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003504 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3505 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3506 // obviously then parallel processing on the cancel must be avoided
3507 // deadline context to ensure completion of background routines waited for
3508 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3509 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3510 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3511
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003512 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003513 var wg sync.WaitGroup
3514 wg.Add(1) // for the 1 go routine to finish
3515
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003516 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003517 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3518
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003519 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003520}
3521
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003522//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003523//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003524func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3525 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003526
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003527 if dh.IsReconciling() {
3528 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003529 return nil
3530 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003531 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003532
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003533 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003534 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003535 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3536 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003537 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003538 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003539
mpagenkof1fc3862021-02-16 10:09:52 +00003540 if aWriteToKvStore {
3541 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3542 }
3543 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003544}
3545
dbainbri4d3a0dc2020-12-02 00:33:42 +00003546func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003547 defer cancel() //ensure termination of context (may be pro forma)
3548 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003549 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003550 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003551}
3552
dbainbri4d3a0dc2020-12-02 00:33:42 +00003553func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003554
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003555 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003556 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003557 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo42dcdfd2021-10-19 17:34:12 -04003558 if err := dh.updateDeviceReasonInCore(ctx, &ca.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003559 DeviceId: dh.DeviceID,
3560 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003561 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003562 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003563 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003564 return err
3565 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003566 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003567 return nil
3568 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003569 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003570 return nil
3571}
3572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003573func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3574 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003575 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003576 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3577 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003578 }
mpagenkof1fc3862021-02-16 10:09:52 +00003579 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003580}
3581
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003582// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003583// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003584func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3585 dh.lockDevice.RLock()
3586 defer dh.lockDevice.RUnlock()
3587 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003588 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003589 }
3590 return 0, errors.New("error-fetching-uni-port")
3591}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003592
3593// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003594func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3595 var errorsList []error
3596 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 -08003597
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003598 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3599 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3600 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3601
3602 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3603 // successfully.
3604 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3605 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3606 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003607 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 -08003608 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003609 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003610 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003611 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003612}
3613
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003614func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3615 var err error
3616 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003617 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003618
3619 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003620 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003621 errorsList = append(errorsList, err)
3622 }
3623 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003624 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003625
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003626 return errorsList
3627}
3628
3629func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3630 var err error
3631 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003632 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003633 // Check if group metric related config is updated
3634 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003635 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3636 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3637 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003638
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003639 if ok && m.Frequency != v.GroupFreq {
3640 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003641 errorsList = append(errorsList, err)
3642 }
3643 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003644 if ok && m.Enabled != v.Enabled {
3645 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003646 errorsList = append(errorsList, err)
3647 }
3648 }
3649 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003650 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003651 return errorsList
3652}
3653
3654func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3655 var err error
3656 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003657 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003658 // Check if standalone metric related config is updated
3659 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3661 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3662 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003663
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003664 if ok && m.Frequency != v.SampleFreq {
3665 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003666 errorsList = append(errorsList, err)
3667 }
3668 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003669 if ok && m.Enabled != v.Enabled {
3670 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003671 errorsList = append(errorsList, err)
3672 }
3673 }
3674 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003675 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003676 return errorsList
3677}
3678
3679// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003680func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003681 logger.Debugf(ctx, "startingCollector")
3682
3683 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003684 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303685 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003686 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003687 // Initialize the next metric collection time.
3688 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3689 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003690 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003691 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003692 for {
3693 select {
3694 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003695 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003696 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003697 // Stop the L2 PM FSM
3698 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3700 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3701 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003702 }
3703 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003704 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003705 }
3706 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003707 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3708 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003709 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003710 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3711 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003712 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003713
Girish Gowdrae09a6202021-01-12 18:10:59 -08003714 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003715 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3716 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3717 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3718 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3719 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003720 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003721 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003722 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003723 } else {
3724 if dh.pmConfigs.Grouped { // metrics are managed as a group
3725 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003726 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003727
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003728 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3729 // 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 -08003730 // 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 +00003731 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3732 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003733 }
3734 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003735 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3736 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3737 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3738 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003739 }
3740 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003741 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003742
3743 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003744 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3745 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3746 // 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 -08003747 // 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 +00003748 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3749 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003750 }
3751 }
3752 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003753 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3754 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3755 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3756 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003757 }
3758 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003759 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003760 } /* else { // metrics are not managed as a group
khenaidoo42dcdfd2021-10-19 17:34:12 -04003761 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metrca.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003762 } */
3763 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003764 }
3765 }
3766}
kesavandfdf77632021-01-26 23:40:33 -05003767
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003768func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003769
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003770 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3771 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003772}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003773
Himani Chawla43f95ff2021-06-03 00:24:12 +05303774func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3775 if dh.pOnuMetricsMgr == nil {
3776 return &extension.SingleGetValueResponse{
3777 Response: &extension.GetValueResponse{
3778 Status: extension.GetValueResponse_ERROR,
3779 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3780 },
3781 }
3782 }
Himani Chawlaee10b542021-09-20 16:46:40 +05303783 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx, onuInfo)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303784 return resp
3785}
3786
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003787func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3788 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003789 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003790 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003791 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003792}
3793
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003794func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
mpagenkofbf577d2021-10-12 11:44:33 +00003795 var pAdapterFsm *cmn.AdapterFsm
3796 //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 +00003797 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003798 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003799 {
mpagenkofbf577d2021-10-12 11:44:33 +00003800 if dh.pOnuOmciDevice != nil {
3801 pAdapterFsm = dh.pOnuOmciDevice.PMibUploadFsm
3802 } else {
3803 return true //FSM not active - so there is no activity on omci
3804 }
mpagenkof1fc3862021-02-16 10:09:52 +00003805 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003806 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003807 {
mpagenkofbf577d2021-10-12 11:44:33 +00003808 if dh.pOnuOmciDevice != nil {
3809 pAdapterFsm = dh.pOnuOmciDevice.PMibDownloadFsm
3810 } else {
3811 return true //FSM not active - so there is no activity on omci
3812 }
mpagenkof1fc3862021-02-16 10:09:52 +00003813 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003814 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003815 {
mpagenkofbf577d2021-10-12 11:44:33 +00003816 if dh.pLockStateFsm != nil {
3817 pAdapterFsm = dh.pLockStateFsm.PAdaptFsm
3818 } else {
3819 return true //FSM not active - so there is no activity on omci
3820 }
mpagenkof1fc3862021-02-16 10:09:52 +00003821 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003822 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003823 {
mpagenkofbf577d2021-10-12 11:44:33 +00003824 if dh.pUnlockStateFsm != nil {
3825 pAdapterFsm = dh.pUnlockStateFsm.PAdaptFsm
3826 } else {
3827 return true //FSM not active - so there is no activity on omci
3828 }
mpagenkof1fc3862021-02-16 10:09:52 +00003829 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003830 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003831 {
mpagenkofbf577d2021-10-12 11:44:33 +00003832 if dh.pOnuMetricsMgr != nil {
3833 pAdapterFsm = dh.pOnuMetricsMgr.PAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003834 } else {
3835 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003836 }
3837 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003838 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003839 {
3840 dh.lockUpgradeFsm.RLock()
3841 defer dh.lockUpgradeFsm.RUnlock()
mpagenkofbf577d2021-10-12 11:44:33 +00003842 if dh.pOnuUpradeFsm != nil {
3843 pAdapterFsm = dh.pOnuUpradeFsm.PAdaptFsm
3844 } else {
3845 return true //FSM not active - so there is no activity on omci
3846 }
mpagenko80622a52021-02-09 16:53:23 +00003847 }
mpagenkof1fc3862021-02-16 10:09:52 +00003848 default:
3849 {
3850 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003851 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003852 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003853 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003854 }
mpagenkofbf577d2021-10-12 11:44:33 +00003855 if pAdapterFsm != nil && pAdapterFsm.PFsm != nil {
3856 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.PFsm, wantedState)
3857 }
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 +00003861func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3862 for _, v := range dh.pOnuTP.PAniConfigFsm {
3863 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003864 return false
3865 }
3866 }
3867 return true
3868}
3869
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003870func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003871 dh.lockVlanConfig.RLock()
3872 defer dh.lockVlanConfig.RUnlock()
3873 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003874 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003875 return false
3876 }
3877 }
3878 return true //FSM not active - so there is no activity on omci
3879}
3880
3881func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3882 dh.lockVlanConfig.RLock()
3883 defer dh.lockVlanConfig.RUnlock()
3884 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003885 if v.PAdaptFsm.PFsm != nil {
3886 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003887 return true //there is at least one VLAN FSM with some active configuration
3888 }
3889 }
3890 }
3891 return false //there is no VLAN FSM with some active configuration
3892}
3893
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003894func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003895 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3896 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3897 return false
3898 }
3899 }
3900 // a further check is done to identify, if at least some data traffic related configuration exists
3901 // 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])
3902 return dh.checkUserServiceExists(ctx)
3903}
3904
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003905func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003906 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3907 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003908 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003909 // TODO: fatal error reset ONU, delete deviceHandler!
3910 return
3911 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003912 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3913 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003914}
3915
3916func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3917 dh.mutexCollectorFlag.Lock()
3918 dh.collectorIsRunning = flagValue
3919 dh.mutexCollectorFlag.Unlock()
3920}
3921
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003922func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003923 dh.mutexCollectorFlag.RLock()
3924 flagValue := dh.collectorIsRunning
3925 dh.mutexCollectorFlag.RUnlock()
3926 return flagValue
3927}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303928
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303929func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3930 dh.mutextAlarmManagerFlag.Lock()
3931 dh.alarmManagerIsRunning = flagValue
3932 dh.mutextAlarmManagerFlag.Unlock()
3933}
3934
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003935func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303936 dh.mutextAlarmManagerFlag.RLock()
3937 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303938 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303939 dh.mutextAlarmManagerFlag.RUnlock()
3940 return flagValue
3941}
3942
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003943func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303944 logger.Debugf(ctx, "startingAlarmManager")
3945
3946 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003947 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303948 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303949 if stop := <-dh.stopAlarmManager; stop {
3950 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303951 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303952 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003953 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3954 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303955 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303956 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003957 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3958 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303959 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303960 }
3961}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003962
Girish Gowdrae95687a2021-09-08 16:30:58 -07003963func (dh *deviceHandler) setFlowMonitoringIsRunning(uniID uint8, flag bool) {
3964 dh.mutexFlowMonitoringRoutineFlag.Lock()
3965 defer dh.mutexFlowMonitoringRoutineFlag.Unlock()
3966 logger.Debugw(context.Background(), "set-flow-monitoring-routine", log.Fields{"flag": flag})
3967 dh.isFlowMonitoringRoutineActive[uniID] = flag
3968}
3969
3970func (dh *deviceHandler) GetFlowMonitoringIsRunning(uniID uint8) bool {
3971 dh.mutexFlowMonitoringRoutineFlag.RLock()
3972 defer dh.mutexFlowMonitoringRoutineFlag.RUnlock()
3973 logger.Debugw(context.Background(), "get-flow-monitoring-routine",
3974 log.Fields{"isFlowMonitoringRoutineActive": dh.isFlowMonitoringRoutineActive})
3975 return dh.isFlowMonitoringRoutineActive[uniID]
3976}
3977
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003978func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3979 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003980
Maninder7961d722021-06-16 22:10:28 +05303981 connectStatus := voltha.ConnectStatus_UNREACHABLE
3982 operState := voltha.OperStatus_UNKNOWN
3983
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003984 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003985 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003986 logger.Debugw(ctx, "wait for channel signal or timeout",
mpagenko101ac942021-11-16 15:01:29 +00003987 log.Fields{"timeout": dh.reconcileExpiryComplete, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003988 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003989 case success := <-dh.chReconcilingFinished:
3990 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003991 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303992 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003993 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303994 } else {
mpagenko2c3f6c52021-11-23 11:22:10 +00003995 onuDevEntry.MutexPersOnuConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003996 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303997 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003998 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3999 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05304000 operState = voltha.OperStatus_ACTIVE
4001 } else {
4002 operState = voltha.OperStatus_ACTIVATING
4003 }
4004 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004005 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
4006 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
4007 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05304008 operState = voltha.OperStatus_DISCOVERED
4009 }
mpagenko2c3f6c52021-11-23 11:22:10 +00004010 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninderb5187552021-03-23 22:23:42 +05304011 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05304012 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004013 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004014 log.Fields{"device-id": dh.DeviceID})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004015 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004016 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004017 ConnStatus: connectStatus,
4018 OperStatus: operState,
4019 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304020 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004021 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304022 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004023 } else {
Maninderb5187552021-03-23 22:23:42 +05304024 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004025 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304026
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004027 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304028 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004029 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004030 } else {
4031 onuDevEntry.MutexPersOnuConfig.RLock()
4032 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4033 connectStatus = voltha.ConnectStatus_REACHABLE
4034 }
4035 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304036 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004037 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004038 }
mpagenko101ac942021-11-16 15:01:29 +00004039 case <-time.After(dh.reconcileExpiryComplete):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004040 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004041 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05304042
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004043 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05304044 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004045 log.Fields{"device-id": dh.DeviceID})
mpagenko2c3f6c52021-11-23 11:22:10 +00004046 } else {
4047 onuDevEntry.MutexPersOnuConfig.RLock()
4048 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
4049 connectStatus = voltha.ConnectStatus_REACHABLE
4050 }
4051 onuDevEntry.MutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05304052 }
4053
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004054 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05304055
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004056 }
4057 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004058 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004059 dh.mutexReconcilingFlag.Unlock()
4060 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004061 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004062 dh.mutexReconcilingFlag.Lock()
4063 if skipOnuConfig {
4064 dh.reconciling = cSkipOnuConfigReconciling
4065 } else {
4066 dh.reconciling = cOnuConfigReconciling
4067 }
4068 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004069}
4070
mpagenko101ac942021-11-16 15:01:29 +00004071func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool, reconcileFlowResult uint16) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004072 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
4073 if dh.IsReconciling() {
mpagenko101ac942021-11-16 15:01:29 +00004074 dh.sendChReconcileFinished(success)
4075 if reconcileFlowResult != cWaitReconcileFlowNoActivity {
4076 dh.SendChUniVlanConfigFinished(reconcileFlowResult)
4077 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004078 } else {
mpagenko101ac942021-11-16 15:01:29 +00004079 logger.Debugw(ctx, "nothing to stop - reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004080 }
4081}
4082
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004083func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004084 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004085 defer dh.mutexReconcilingFlag.RUnlock()
4086 return dh.reconciling != cNoReconciling
4087}
4088
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004089func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004090 dh.mutexReconcilingFlag.RLock()
4091 defer dh.mutexReconcilingFlag.RUnlock()
4092 return dh.reconciling == cSkipOnuConfigReconciling
4093}
4094
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004095func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004096 dh.mutexDeviceReason.Lock()
4097 dh.deviceReason = value
4098 dh.mutexDeviceReason.Unlock()
4099}
4100
4101func (dh *deviceHandler) getDeviceReason() uint8 {
4102 dh.mutexDeviceReason.RLock()
4103 value := dh.deviceReason
4104 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00004105 return value
4106}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004107
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004108func (dh *deviceHandler) GetDeviceReasonString() string {
4109 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00004110}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00004111
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004112func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004113 dh.mutexReadyForOmciConfig.Lock()
4114 dh.readyForOmciConfig = flagValue
4115 dh.mutexReadyForOmciConfig.Unlock()
4116}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004117func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00004118 dh.mutexReadyForOmciConfig.RLock()
4119 flagValue := dh.readyForOmciConfig
4120 dh.mutexReadyForOmciConfig.RUnlock()
4121 return flagValue
4122}
Maninder7961d722021-06-16 22:10:28 +05304123
4124func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
4125 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
4126 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004127 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304128 }
4129
4130 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo42dcdfd2021-10-19 17:34:12 -04004131 if err := dh.updateDeviceStateInCore(ctx, &ca.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004132 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04004133 ConnStatus: connectStatus,
4134 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
4135 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05304136 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004137 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05304138 }
4139}
khenaidoo7d3c5582021-08-11 18:09:44 -04004140
4141/*
4142Helper functions to communicate with Core
4143*/
4144
4145func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
4146 cClient, err := dh.coreClient.GetCoreServiceClient()
4147 if err != nil || cClient == nil {
4148 return nil, err
4149 }
4150 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4151 defer cancel()
4152 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
4153 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
4154}
4155
khenaidoo42dcdfd2021-10-19 17:34:12 -04004156func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ca.DeviceStateFilter) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004157 cClient, err := dh.coreClient.GetCoreServiceClient()
4158 if err != nil || cClient == nil {
4159 return err
4160 }
4161 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4162 defer cancel()
4163 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
4164 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
4165 return err
4166}
4167
4168func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
4169 cClient, err := dh.coreClient.GetCoreServiceClient()
4170 if err != nil || cClient == nil {
4171 return err
4172 }
4173 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4174 defer cancel()
4175 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
4176 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
4177 return err
4178}
4179
4180func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
4181 cClient, err := dh.coreClient.GetCoreServiceClient()
4182 if err != nil || cClient == nil {
4183 return err
4184 }
4185 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4186 defer cancel()
4187 _, err = cClient.DeviceUpdate(subCtx, device)
4188 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
4189 return err
4190}
4191
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004192func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004193 cClient, err := dh.coreClient.GetCoreServiceClient()
4194 if err != nil || cClient == nil {
4195 return err
4196 }
4197 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4198 defer cancel()
4199 _, err = cClient.PortCreated(subCtx, port)
4200 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
4201 return err
4202}
4203
khenaidoo42dcdfd2021-10-19 17:34:12 -04004204func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ca.PortState) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004205 cClient, err := dh.coreClient.GetCoreServiceClient()
4206 if err != nil || cClient == nil {
4207 return err
4208 }
4209 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4210 defer cancel()
4211 _, err = cClient.PortStateUpdate(subCtx, portState)
4212 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
4213 return err
4214}
4215
khenaidoo42dcdfd2021-10-19 17:34:12 -04004216func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ca.DeviceReason) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004217 cClient, err := dh.coreClient.GetCoreServiceClient()
4218 if err != nil || cClient == nil {
4219 return err
4220 }
4221 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
4222 defer cancel()
4223 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
4224 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
4225 return err
4226}
4227
4228/*
4229Helper functions to communicate with parent adapter
4230*/
4231
4232func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
khenaidoo42dcdfd2021-10-19 17:34:12 -04004233 request *ia.TechProfileInstanceRequestMessage) (*ia.TechProfileDownloadMessage, error) {
khenaidoo7d3c5582021-08-11 18:09:44 -04004234 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4235 if err != nil || pgClient == nil {
4236 return nil, err
4237 }
4238 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4239 defer cancel()
4240 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4241 return pgClient.GetTechProfileInstance(subCtx, request)
4242}
4243
Girish Gowdrae95687a2021-09-08 16:30:58 -07004244// This routine is unique per ONU ID and blocks on flowControlBlock channel for incoming flows
4245// Each incoming flow is processed in a synchronous manner, i.e., the flow is processed to completion before picking another
4246func (dh *deviceHandler) PerOnuFlowHandlerRoutine(uniID uint8) {
4247 logger.Infow(context.Background(), "starting-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4248 dh.setFlowMonitoringIsRunning(uniID, true)
4249 for {
4250 select {
4251 // block on the channel to receive an incoming flow
4252 // process the flow completely before proceeding to handle the next flow
4253 case flowCb := <-dh.flowCbChan[uniID]:
4254 startTime := time.Now()
4255 logger.Debugw(flowCb.ctx, "serial-flow-processor--start", log.Fields{"device-id": dh.DeviceID})
4256 respChan := make(chan error)
4257 if flowCb.addFlow {
4258 go dh.addFlowItemToUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, flowCb.flowMetaData, &respChan)
4259 } else {
4260 go dh.removeFlowItemFromUniPort(flowCb.ctx, flowCb.flowItem, flowCb.uniPort, &respChan)
4261 }
4262 // Block on response and tunnel it back to the caller
4263 *flowCb.respChan <- <-respChan
4264 logger.Debugw(flowCb.ctx, "serial-flow-processor--end",
4265 log.Fields{"device-id": dh.DeviceID, "absoluteTimeForFlowProcessingInSecs": time.Since(startTime).Seconds()})
4266 case <-dh.stopFlowMonitoringRoutine[uniID]:
4267 logger.Infow(context.Background(), "stopping-flow-handler-routine", log.Fields{"device-id": dh.DeviceID})
4268 dh.setFlowMonitoringIsRunning(uniID, false)
4269 return
4270 }
4271 }
4272}
4273
khenaidoo42dcdfd2021-10-19 17:34:12 -04004274func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ia.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04004275 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
4276 if err != nil || pgClient == nil {
4277 return err
4278 }
4279 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
4280 defer cancel()
4281 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
4282 _, err = pgClient.ProxyOmciRequest(subCtx, request)
4283 if err != nil {
4284 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
4285 }
4286 return err
4287}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004288
4289// GetDeviceID - TODO: add comment
4290func (dh *deviceHandler) GetDeviceID() string {
4291 return dh.DeviceID
4292}
4293
4294// GetProxyAddressID - TODO: add comment
4295func (dh *deviceHandler) GetProxyAddressID() string {
4296 return dh.device.ProxyAddress.GetDeviceId()
4297}
4298
4299// GetProxyAddressType - TODO: add comment
4300func (dh *deviceHandler) GetProxyAddressType() string {
4301 return dh.device.ProxyAddress.GetDeviceType()
4302}
4303
4304// GetProxyAddress - TODO: add comment
4305func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
4306 return dh.device.ProxyAddress
4307}
4308
4309// GetEventProxy - TODO: add comment
4310func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
4311 return dh.EventProxy
4312}
4313
4314// GetOmciTimeout - TODO: add comment
4315func (dh *deviceHandler) GetOmciTimeout() int {
4316 return dh.pOpenOnuAc.omciTimeout
4317}
4318
4319// GetAlarmAuditInterval - TODO: add comment
4320func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
4321 return dh.pOpenOnuAc.alarmAuditInterval
4322}
4323
4324// GetDlToOnuTimeout4M - TODO: add comment
4325func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
4326 return dh.pOpenOnuAc.dlToOnuTimeout4M
4327}
4328
4329// GetUniEntityMap - TODO: add comment
4330func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
4331 return &dh.uniEntityMap
4332}
4333
4334// GetPonPortNumber - TODO: add comment
4335func (dh *deviceHandler) GetPonPortNumber() *uint32 {
4336 return &dh.ponPortNumber
4337}
4338
4339// GetUniVlanConfigFsm - TODO: add comment
4340func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00004341 dh.lockVlanConfig.RLock()
4342 value := dh.UniVlanConfigFsmMap[uniID]
4343 dh.lockVlanConfig.RUnlock()
4344 return value
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00004345}
4346
4347// GetOnuAlarmManager - TODO: add comment
4348func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
4349 return dh.pAlarmMgr
4350}
4351
4352// GetOnuMetricsManager - TODO: add comment
4353func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
4354 return dh.pOnuMetricsMgr
4355}
4356
4357// GetOnuTP - TODO: add comment
4358func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
4359 return dh.pOnuTP
4360}
4361
4362// GetBackendPathPrefix - TODO: add comment
4363func (dh *deviceHandler) GetBackendPathPrefix() string {
4364 return dh.pOpenOnuAc.cm.Backend.PathPrefix
4365}
4366
4367// GetOnuIndication - TODO: add comment
4368func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
4369 return dh.pOnuIndication
4370}
4371
4372// RLockMutexDeletionInProgressFlag - TODO: add comment
4373func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
4374 dh.mutexDeletionInProgressFlag.RLock()
4375}
4376
4377// RUnlockMutexDeletionInProgressFlag - TODO: add comment
4378func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
4379 dh.mutexDeletionInProgressFlag.RUnlock()
4380}
4381
4382// GetDeletionInProgress - TODO: add comment
4383func (dh *deviceHandler) GetDeletionInProgress() bool {
4384 return dh.deletionInProgress
4385}
4386
4387// GetPmConfigs - TODO: add comment
4388func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
4389 return dh.pmConfigs
4390}
4391
4392// GetDeviceType - TODO: add comment
4393func (dh *deviceHandler) GetDeviceType() string {
4394 return dh.DeviceType
4395}
4396
4397// GetLogicalDeviceID - TODO: add comment
4398func (dh *deviceHandler) GetLogicalDeviceID() string {
4399 return dh.logicalDeviceID
4400}
4401
4402// GetDevice - TODO: add comment
4403func (dh *deviceHandler) GetDevice() *voltha.Device {
4404 return dh.device
4405}
4406
4407// GetMetricsEnabled - TODO: add comment
4408func (dh *deviceHandler) GetMetricsEnabled() bool {
4409 return dh.pOpenOnuAc.MetricsEnabled
4410}
4411
4412// InitPmConfigs - TODO: add comment
4413func (dh *deviceHandler) InitPmConfigs() {
4414 dh.pmConfigs = &voltha.PmConfigs{}
4415}
4416
4417// GetUniPortMask - TODO: add comment
4418func (dh *deviceHandler) GetUniPortMask() int {
4419 return dh.pOpenOnuAc.config.UniPortMask
4420}