blob: 537533c3d112f9120706636a5c8c3f3af4037a87 [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"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000029 "github.com/opencord/voltha-protos/v5/go/openolt"
khenaidoo7d3c5582021-08-11 18:09:44 -040030 "github.com/opencord/voltha-protos/v5/go/tech_profile"
mpagenko1f8e8822021-06-25 14:10:21 +000031
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000032 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000033 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000034 me "github.com/opencord/omci-lib-go/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040035 "github.com/opencord/voltha-lib-go/v7/pkg/db"
36 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
37 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
38 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
39 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000040 almgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/almgr"
41 avcfg "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/avcfg"
42 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
43 mib "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/mib"
44 otst "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/omcitst"
45 pmmgr "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/pmmgr"
46 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/swupg"
47 uniprt "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/uniprt"
khenaidoo7d3c5582021-08-11 18:09:44 -040048 vc "github.com/opencord/voltha-protos/v5/go/common"
49 "github.com/opencord/voltha-protos/v5/go/extension"
50 ic "github.com/opencord/voltha-protos/v5/go/inter_container"
51 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
52 oop "github.com/opencord/voltha-protos/v5/go/openolt"
53 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000054)
55
mpagenko38662d02021-08-11 09:45:19 +000056// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000057const (
mpagenko38662d02021-08-11 09:45:19 +000058 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000059)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000060
mpagenko1cc3cb42020-07-27 15:24:38 +000061const (
62 // events of Device FSM
63 devEvDeviceInit = "devEvDeviceInit"
64 devEvGrpcConnected = "devEvGrpcConnected"
65 devEvGrpcDisconnected = "devEvGrpcDisconnected"
66 devEvDeviceUpInd = "devEvDeviceUpInd"
67 devEvDeviceDownInd = "devEvDeviceDownInd"
68)
69const (
70 // states of Device FSM
71 devStNull = "devStNull"
72 devStDown = "devStDown"
73 devStInit = "devStInit"
74 devStConnected = "devStConnected"
75 devStUp = "devStUp"
76)
77
Holger Hildebrandt24d51952020-05-04 14:03:42 +000078//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
79const (
Himani Chawla4d908332020-08-31 12:30:20 +053080 pon = voltha.EventSubCategory_PON
81 //olt = voltha.EventSubCategory_OLT
82 //ont = voltha.EventSubCategory_ONT
83 //onu = voltha.EventSubCategory_ONU
84 //nni = voltha.EventSubCategory_NNI
85 //service = voltha.EventCategory_SERVICE
86 //security = voltha.EventCategory_SECURITY
87 equipment = voltha.EventCategory_EQUIPMENT
88 //processing = voltha.EventCategory_PROCESSING
89 //environment = voltha.EventCategory_ENVIRONMENT
90 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000091)
92
93const (
94 cEventObjectType = "ONU"
95)
96const (
97 cOnuActivatedEvent = "ONU_ACTIVATED"
98)
99
mpagenkof1fc3862021-02-16 10:09:52 +0000100type omciIdleCheckStruct struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000101 omciIdleCheckFunc func(*deviceHandler, context.Context, cmn.UsedOmciConfigFsms, string) bool
mpagenkof1fc3862021-02-16 10:09:52 +0000102 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000103}
104
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000105var fsmOmciIdleStateFuncMap = map[cmn.UsedOmciConfigFsms]omciIdleCheckStruct{
106 cmn.CUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibUlFsmIdleState},
107 cmn.CDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, mib.CMibDlFsmIdleState},
108 cmn.CUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
109 cmn.CUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, uniprt.CUniFsmIdleState},
110 cmn.CAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, avcfg.CAniFsmIdleState},
111 cmn.CUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, avcfg.CVlanFsmIdleState},
112 cmn.CL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, pmmgr.CL2PmFsmIdleState},
113 cmn.COnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, swupg.COnuUpgradeFsmIdleState},
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000114}
115
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000116const (
117 cNoReconciling = iota
118 cOnuConfigReconciling
119 cSkipOnuConfigReconciling
120)
121
Himani Chawla6d2ae152020-09-02 13:11:20 +0530122//deviceHandler will interact with the ONU ? device.
123type deviceHandler struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000124 DeviceID string
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000125 DeviceType string
126 adminState string
127 device *voltha.Device
128 logicalDeviceID string
129 ProxyAddressID string
130 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530131 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000132 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000133
khenaidoo7d3c5582021-08-11 18:09:44 -0400134 coreClient *vgrpc.Client
135 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000136
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800137 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400138 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800139
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000140 pOpenOnuAc *OpenONUAC
141 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530142 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000143 deviceEntrySet chan bool //channel for DeviceEntry set event
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000144 pOnuOmciDevice *mib.OnuDeviceEntry
145 pOnuTP *avcfg.OnuUniTechProf
146 pOnuMetricsMgr *pmmgr.OnuMetricsManager
147 pAlarmMgr *almgr.OnuAlarmManager
148 pSelfTestHdlr *otst.SelfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000149 exitChannel chan int
150 lockDevice sync.RWMutex
151 pOnuIndication *oop.OnuIndication
152 deviceReason uint8
153 mutexDeviceReason sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000154 pLockStateFsm *uniprt.LockStateFsm
155 pUnlockStateFsm *uniprt.LockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000156
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000157 //flowMgr *OpenOltFlowMgr
158 //eventMgr *OpenOltEventMgr
159 //resourceMgr *rsrcMgr.OpenOltResourceMgr
160
161 //discOnus sync.Map
162 //onus sync.Map
163 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000164 collectorIsRunning bool
165 mutexCollectorFlag sync.RWMutex
166 stopCollector chan bool
167 alarmManagerIsRunning bool
168 mutextAlarmManagerFlag sync.RWMutex
169 stopAlarmManager chan bool
170 stopHeartbeatCheck chan bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000171 uniEntityMap cmn.OnuUniPortMap
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000172 mutexKvStoreContext sync.Mutex
173 lockVlanConfig sync.RWMutex
mpagenkobc4170a2021-08-17 16:42:10 +0000174 lockVlanAdd sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000175 UniVlanConfigFsmMap map[uint8]*avcfg.UniVlanConfigFsm
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000176 lockUpgradeFsm sync.RWMutex
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000177 pOnuUpradeFsm *swupg.OnuUpgradeFsm
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000178 reconciling uint8
179 mutexReconcilingFlag sync.RWMutex
180 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000181 mutexReadyForOmciConfig sync.RWMutex
182 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000183 deletionInProgress bool
184 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000185 pLastUpgradeImageState *voltha.ImageState
186 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187}
188
Himani Chawla6d2ae152020-09-02 13:11:20 +0530189//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400190func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530191 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400192 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000193 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400194 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000195 cloned := (proto.Clone(device)).(*voltha.Device)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000196 dh.DeviceID = cloned.Id
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 dh.DeviceType = cloned.Type
198 dh.adminState = "up"
199 dh.device = cloned
200 dh.pOpenOnuAc = adapter
201 dh.exitChannel = make(chan int, 1)
202 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000203 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000204 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000205 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530206 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530207 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208 dh.stopHeartbeatCheck = make(chan bool, 2)
209 //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 +0000210 //TODO initialize the support classes.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000211 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000212 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000213 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000214 dh.lockUpgradeFsm = sync.RWMutex{}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000215 dh.UniVlanConfigFsmMap = make(map[uint8]*avcfg.UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000216 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000217 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000218 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000219 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000220 dh.pLastUpgradeImageState = &voltha.ImageState{
221 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
222 Reason: voltha.ImageState_UNKNOWN_ERROR,
223 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
224 }
225 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800227 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
228 dh.pmConfigs = cloned.PmConfigs
229 } /* else {
230 // will be populated when onu_metrics_mananger is initialized.
231 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800232
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000233 // Device related state machine
234 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000235 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000236 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000237 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
238 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
239 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
240 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
241 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 },
243 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000244 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
245 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
246 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
247 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
248 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
249 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
250 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
251 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000252 },
253 )
mpagenkoaf801632020-07-03 10:00:42 +0000254
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 return &dh
256}
257
Himani Chawla6d2ae152020-09-02 13:11:20 +0530258// start save the device to the data model
259func (dh *deviceHandler) start(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000260 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000263}
264
Himani Chawla4d908332020-08-31 12:30:20 +0530265/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000266// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530267func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 logger.Debug("stopping-device-handler")
269 dh.exitChannel <- 1
270}
Himani Chawla4d908332020-08-31 12:30:20 +0530271*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000272
273// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530274// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000275
Girish Gowdrae0140f02021-02-02 16:55:09 -0800276//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530277func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400278 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000281 if dh.pDeviceStateFsm.Is(devStNull) {
282 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000283 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800286 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
287 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800288 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400289 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000290 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800291 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800292 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000293 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 }
296
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297}
298
khenaidoo7d3c5582021-08-11 18:09:44 -0400299func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ic.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000300 /* 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 +0530301 //assuming omci message content is hex coded!
302 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000303 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000304 "device-id": dh.DeviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000305 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000306 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530307 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000308 if pDevEntry.PDevOmciCC != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000309 return pDevEntry.PDevOmciCC.ReceiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000310 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400311 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 +0530312 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000313 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
314 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530315}
316
khenaidoo7d3c5582021-08-11 18:09:44 -0400317func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ic.TechProfileDownloadMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000318 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000319
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000320 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000321 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000322 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
323 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000324 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530325 if dh.pOnuTP == nil {
326 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328 log.Fields{"device-id": dh.DeviceID})
329 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530330 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000331 if !dh.IsReadyForOmciConfig() {
332 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
333 "device-state": dh.GetDeviceReasonString()})
334 return fmt.Errorf("improper device state %s on device %s", dh.GetDeviceReasonString(), dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000336 //previous state test here was just this one, now extended for more states to reject the SetRequest:
337 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
338 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530339
Himani Chawla26e555c2020-08-31 12:30:20 +0530340 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000341 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
342 // to possible concurrent access by flow processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000343 dh.pOnuTP.LockTpProcMutex()
344 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000345
346 if techProfMsg.UniId > 255 {
347 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 techProfMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000349 }
350 uniID := uint8(techProfMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000351 tpID, err := cmn.GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800352 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700353 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800354 return err
355 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700356 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000358 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530359
Girish Gowdra50e56422021-06-01 16:46:04 -0700360 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400361 case *ic.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700362 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
363 // if there has been some change for some uni TechProfilePath
364 //in order to allow concurrent calls to other dh instances we do not wait for execution here
365 //but doing so we can not indicate problems to the caller (who does what with that then?)
366 //by now we just assume straightforward successful execution
367 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
368 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530369
Girish Gowdra50e56422021-06-01 16:46:04 -0700370 // deadline context to ensure completion of background routines waited for
371 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
372 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
373 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Girish Gowdra50e56422021-06-01 16:46:04 -0700376
377 var wg sync.WaitGroup
378 wg.Add(1) // for the 1 go routine to finish
379 // attention: deadline completion check and wg.Done is to be done in both routines
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000380 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700381 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 if tpErr := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
383 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 -0700384 return tpErr
385 }
386 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
387 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000388 pDevEntry.ResetKvProcessingErrorIndication()
Girish Gowdra50e56422021-06-01 16:46:04 -0700389 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000390 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
Girish Gowdra50e56422021-06-01 16:46:04 -0700391 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000392 if kvErr := pDevEntry.GetKvProcessingErrorIndication(); kvErr != nil {
393 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 -0700394 return kvErr
395 }
396 return nil
397 default:
398 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
399 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700400 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530401 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000402 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700403 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 +0530404 return nil
405}
406
khenaidoo7d3c5582021-08-11 18:09:44 -0400407func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ic.DeleteGemPortMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000408 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530409
410 if dh.pOnuTP == nil {
411 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000412 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000413 log.Fields{"device-id": dh.DeviceID})
414 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530416 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000417 dh.pOnuTP.LockTpProcMutex()
418 defer dh.pOnuTP.UnlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530419
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000420 if delGemPortMsg.UniId > 255 {
421 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000422 delGemPortMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000423 }
424 uniID := uint8(delGemPortMsg.UniId)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000425 tpID, err := cmn.GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800426 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700427 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800428 return err
429 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000430 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000431 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432
Mahir Gunyel9545be22021-07-04 15:53:16 -0700433 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000434 avcfg.CResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000435
Himani Chawla26e555c2020-08-31 12:30:20 +0530436}
437
khenaidoo7d3c5582021-08-11 18:09:44 -0400438func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ic.DeleteTcontMessage) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000439 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000440
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000441 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000442 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000443 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
444 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000445 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530446 if dh.pOnuTP == nil {
447 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000449 log.Fields{"device-id": dh.DeviceID})
450 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530451 }
452
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 //compare TECH_PROFILE_DOWNLOAD_REQUEST
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000454 dh.pOnuTP.LockTpProcMutex()
455 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000456
457 if delTcontMsg.UniId > 255 {
458 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000459 delTcontMsg.UniId, dh.DeviceID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000460 }
461 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700462 tpPath := delTcontMsg.TpInstancePath
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000463 tpID, err := cmn.GetTpIDFromTpPath(tpPath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800464 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000465 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800466 return err
467 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000468 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 +0000469
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000470 pDevEntry.FreeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530471
Mahir Gunyel9545be22021-07-04 15:53:16 -0700472 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000473 avcfg.CResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000474
Mahir Gunyel9545be22021-07-04 15:53:16 -0700475}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000476
Mahir Gunyel9545be22021-07-04 15:53:16 -0700477func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000478 uniID uint8, tpID uint8, pathString string, resource avcfg.ResourceEntry, entryID uint32) error {
479 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700480 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000481 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
482 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530483 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700484 var resourceName string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000485 if avcfg.CResourceGemPort == resource {
Mahir Gunyel9545be22021-07-04 15:53:16 -0700486 resourceName = "Gem"
487 } else {
488 resourceName = "Tcont"
489 }
490
491 // deadline context to ensure completion of background routines waited for
492 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
493 dctx, cancel := context.WithDeadline(context.Background(), deadline)
494
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 dh.pOnuTP.ResetTpProcessingErrorIndication(uniID, tpID)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700496
497 var wg sync.WaitGroup
498 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000499 go dh.pOnuTP.DeleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700500 resource, entryID, &wg)
501 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000502 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniID, tpID); err != nil {
503 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700504 return err
505 }
506
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000507 if dh.pOnuTP.IsTechProfileConfigCleared(ctx, uniID, tpID) {
508 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
509 if bTpModify := pDevEntry.UpdateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
510 pDevEntry.ResetKvProcessingErrorIndication()
Mahir Gunyel9545be22021-07-04 15:53:16 -0700511 var wg2 sync.WaitGroup
512 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
513 wg2.Add(1)
514 // Removal of the gem id mapping represents the removal of the tech profile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000515 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.DeviceID, "uni-id": uniID, "tpID": tpID})
516 go pDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
Mahir Gunyel9545be22021-07-04 15:53:16 -0700517 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000518 if err := pDevEntry.GetKvProcessingErrorIndication(); err != nil {
519 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Mahir Gunyel9545be22021-07-04 15:53:16 -0700520 return err
521 }
522 }
523 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000524 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.DeviceID,
Mahir Gunyel9545be22021-07-04 15:53:16 -0700525 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530526 return nil
527}
528
mpagenkodff5dda2020-08-28 11:52:01 +0000529//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400531 apOfFlowChanges *of.FlowChanges,
532 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.DeviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000534 var retError error = nil
535 //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 +0000536 if apOfFlowChanges.ToRemove != nil {
537 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000538 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000540 "device-id": dh.DeviceID})
541 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000542 continue
543 }
544 flowInPort := flow.GetInPort(flowItem)
545 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000546 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
547 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000548 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000549 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000550 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000551 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000552 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000554 continue
555 } else {
556 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 var loUniPort *cmn.OnuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000558 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
559 loUniPort = uniPort
560 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000563 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 flowInPort, dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000565 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000566 }
567 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
570 "uniPortName": loUniPort.Name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000572 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000573 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000574 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000576 retError = err
577 continue
578 //return err
579 } else { // if last setting succeeds, overwrite possibly previously set error
580 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000581 }
582 }
583 }
584 }
mpagenko01e726e2020-10-23 09:45:29 +0000585 if apOfFlowChanges.ToAdd != nil {
586 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
587 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000588 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000589 "device-id": dh.DeviceID})
590 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000591 continue
592 }
593 flowInPort := flow.GetInPort(flowItem)
594 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.DeviceID})
596 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000597 continue
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 //return fmt.Errorf("flow inPort invalid: %s", dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000599 } else if flowInPort == dh.ponPortNumber {
600 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000601 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 "device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000603 continue
604 } else {
605 // this is the relevant upstream flow
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 var loUniPort *cmn.OnuUniPort
mpagenko01e726e2020-10-23 09:45:29 +0000607 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
608 loUniPort = uniPort
609 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000610 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 log.Fields{"device-id": dh.DeviceID, "inPort": flowInPort})
mpagenko01e726e2020-10-23 09:45:29 +0000612 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 flowInPort, dh.DeviceID)
mpagenko01e726e2020-10-23 09:45:29 +0000614 continue
615 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
616 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000617 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
618 // if not, we just throw some error here to have an indication about that, if we really need to support that
619 // then we would need to create some means to activate the internal stored flows
620 // after the device gets active automatically (and still with its dependency to the TechProfile)
621 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
622 // also abort for the other still possible flows here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623 if !dh.IsReadyForOmciConfig() {
624 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.DeviceID,
625 "last device-reason": dh.GetDeviceReasonString()})
626 return fmt.Errorf("improper device state on device %s", dh.DeviceID)
mpagenkofc4f56e2020-11-04 17:17:49 +0000627 }
628
mpagenko01e726e2020-10-23 09:45:29 +0000629 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "flow-add port indications", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000631 "device-id": dh.DeviceID, "inPort": flowInPort, "outPort": flowOutPort,
632 "uniPortName": loUniPort.Name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300633 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000634 //try next flow after processing error
635 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000638 retError = err
639 continue
640 //return err
641 } else { // if last setting succeeds, overwrite possibly previously set error
642 retError = nil
643 }
644 }
645 }
646 }
647 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000648}
649
Himani Chawla6d2ae152020-09-02 13:11:20 +0530650//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000651//following are the expected device states after this activity:
652//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
653// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
655 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000656
mpagenko900ee4b2020-10-12 11:56:34 +0000657 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000658 //note that disableDevice sequences in some 'ONU active' state may yield also
659 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000660 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 if dh.getDeviceReason() != cmn.DrOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000662 //disable-device shall be just a UNi/ONU-G related admin state setting
663 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000664
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000665 if dh.IsReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000666 // disable UNI ports/ONU
667 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
668 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000669 dh.createUniLockFsm(ctx, true, cmn.UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000670 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 dh.pLockStateFsm.SetSuccessEvent(cmn.UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000673 }
674 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000676 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -0400677 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -0400679 ConnStatus: voltha.ConnectStatus_REACHABLE,
680 OperStatus: voltha.OperStatus_UNKNOWN,
681 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000682 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000683 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000684 }
mpagenko01e726e2020-10-23 09:45:29 +0000685 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000686
687 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000688 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000689 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300690 }
691}
692
Himani Chawla6d2ae152020-09-02 13:11:20 +0530693//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
695 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000696
mpagenkoaa3afe92021-05-21 16:20:58 +0000697 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000698 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
699 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
700 // for real ONU's that should have nearly no influence
701 // Note that for real ONU's there is anyway a problematic situation with following sequence:
702 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
703 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
704 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000705 dh.SetReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000706
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000707 // enable ONU/UNI ports
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000708 // *** should generate cmn.UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000709 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000710 dh.createUniLockFsm(ctx, false, cmn.UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000711 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000712 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000713 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000714 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300715}
716
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000718 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000719
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000720 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000721 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000722 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000723 return
724 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000725 if err := pDevEntry.RestoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000726 if err == fmt.Errorf("no-ONU-data-found") {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000727 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000728 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000729 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000730 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000731 dh.StopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000732 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000733 }
Himani Chawla4d908332020-08-31 12:30:20 +0530734 var onuIndication oop.OnuIndication
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000735 pDevEntry.MutexPersOnuConfig.RLock()
736 onuIndication.IntfId = pDevEntry.SOnuPersistentData.PersIntfID
737 onuIndication.OnuId = pDevEntry.SOnuPersistentData.PersOnuID
738 onuIndication.OperState = pDevEntry.SOnuPersistentData.PersOperState
739 onuIndication.AdminState = pDevEntry.SOnuPersistentData.PersAdminState
740 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000741 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000742}
743
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000744func (dh *deviceHandler) ReconcileDeviceTechProf(ctx context.Context) {
745 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000747 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000748 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000749 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
750 if !dh.IsSkipOnuConfigReconciling() {
751 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000752 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000753 return
754 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000755 dh.pOnuTP.LockTpProcMutex()
756 defer dh.pOnuTP.UnlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000757
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000758 pDevEntry.MutexPersOnuConfig.RLock()
mpagenko2dc896e2021-08-02 12:03:59 +0000759 persMutexLock := true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000760 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
761 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000762 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000763 log.Fields{"device-id": dh.DeviceID})
764 if !dh.IsSkipOnuConfigReconciling() {
765 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000766 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000767 return
768 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000769 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700770 techProfsFound := false
771 techProfInstLoadFailed := false
772outerLoop:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000773 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000774 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
775 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000776 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000777 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000778 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000779 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000780 //release MutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
781 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000782 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000783 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000784 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700785 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800786 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700787 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400788 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
789 dh.device.ProxyAddress.AdapterEndpoint,
790 &ic.TechProfileInstanceRequestMessage{
791 DeviceId: dh.device.Id,
792 TpInstancePath: uniData.PersTpPathMap[tpID],
793 ParentDeviceId: dh.parentID,
794 ParentPonPort: dh.device.ParentPortNo,
795 OnuId: dh.device.ProxyAddress.OnuId,
796 UniId: uint32(uniData.PersUniID),
797 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700798 if err != nil || iaTechTpInst == nil {
799 logger.Errorw(ctx, "error fetching tp instance",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800 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 -0700801 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
802 break outerLoop
803 }
804 var tpInst tech_profile.TechProfileInstance
805 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400806 case *ic.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700807 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000808 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000809 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700810 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000811 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000812 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700813 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
814 break outerLoop
815 }
816
Girish Gowdra041dcb32020-11-16 16:54:30 -0800817 // deadline context to ensure completion of background routines waited for
818 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
819 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000820 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000821
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000822 dh.pOnuTP.ResetTpProcessingErrorIndication(uniData.PersUniID, tpID)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800823 var wg sync.WaitGroup
824 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000825 go dh.pOnuTP.ConfigureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000827 if err := dh.pOnuTP.GetTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
828 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700829 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
830 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800831 }
mpagenko2dc896e2021-08-02 12:03:59 +0000832 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000833 if len(uniData.PersFlowParams) != 0 {
834 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000836 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
mpagenko2dc896e2021-08-02 12:03:59 +0000837 persMutexLock = true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 } // for all UNI entries from SOnuPersistentData
839 if persMutexLock { // if loop was left with MutexPersOnuConfig still set
840 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000841 }
mpagenko2dc896e2021-08-02 12:03:59 +0000842
843 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
844 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
845}
846
847func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
848 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
849 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000850 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000851 log.Fields{"device-id": dh.DeviceID})
852 if !dh.IsSkipOnuConfigReconciling() {
853 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000854 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000855 return
856 }
mpagenko2dc896e2021-08-02 12:03:59 +0000857 if abTechProfInstLoadFailed {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadFailed)
859 dh.StopReconciling(ctx, false)
Girish Gowdra50e56422021-06-01 16:46:04 -0700860 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 } else if dh.IsSkipOnuConfigReconciling() {
862 dh.SetDeviceReason(cmn.DrTechProfileConfigDownloadSuccess)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000863 }
mpagenko2dc896e2021-08-02 12:03:59 +0000864 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000865 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 log.Fields{"device-id": dh.DeviceID})
867 if !dh.IsSkipOnuConfigReconciling() {
868 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000869 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000870 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000871}
872
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873func (dh *deviceHandler) ReconcileDeviceFlowConfig(ctx context.Context) {
874 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000875
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000877 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
879 if !dh.IsSkipOnuConfigReconciling() {
880 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000881 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000882 return
883 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000884
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000885 pDevEntry.MutexPersOnuConfig.RLock()
886 if len(pDevEntry.SOnuPersistentData.PersUniConfig) == 0 {
887 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000889 log.Fields{"device-id": dh.DeviceID})
890 if !dh.IsSkipOnuConfigReconciling() {
891 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000892 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000893 return
894 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000895 flowsFound := false
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000896 for _, uniData := range pDevEntry.SOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000897 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
898 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000900 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 continue
902 }
903 if len(uniData.PersTpPathMap) == 0 {
904 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000905 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.DeviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000906 // It doesn't make sense to configure any flows if no TPs are available
907 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000908 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 //release MutexPersOnuConfig before VlanConfig processing as otherwise the reception of
910 // OMCI frames may get completely stuck due to lock request within IncrementMibDataSync() at OMCI
mpagenko2dc896e2021-08-02 12:03:59 +0000911 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000912 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000913
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 var uniPort *cmn.OnuUniPort
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000915 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000916 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000917 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000918 logger.Errorw(ctx, "reconciling - OnuUniPort data not found - terminate reconcilement",
919 log.Fields{"uniNo": uniNo, "device-id": dh.DeviceID})
920 if !dh.IsSkipOnuConfigReconciling() {
921 dh.StopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000923 return
924 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000925 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200926 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000927 flowsProcessed := 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000928 pDevEntry.SetReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000929 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +0000930 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000931 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200932 if flowsProcessed == len(uniData.PersFlowParams)-1 {
933 lastFlowToReconcile = true
934 }
mpagenko01e726e2020-10-23 09:45:29 +0000935 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +0000936 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000937 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000938 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000939 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +0300940 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000942 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000943 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000945 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946 uint8(flowData.VlanRuleParams.SetPcp), cmn.OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
947 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000948 }
949 }
mpagenko7d14de12021-07-27 08:31:56 +0000950 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000951 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +0000952 } //for all flows of this UNI
953 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 "device-id": dh.DeviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
955 "NumUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].NumUniFlows,
956 "ConfiguredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].ConfiguredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200957 // this can't be used as global finished reconciling flag because
958 // assumes is getting called before the state machines for the last flow is completed,
959 // while this is not guaranteed.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 //dh.SetReconcilingFlows(false)
961 pDevEntry.MutexPersOnuConfig.RLock() //set protection again for loop test on SOnuPersistentData
962 } // for all UNI entries from SOnuPersistentData
963 pDevEntry.MutexPersOnuConfig.RUnlock()
mpagenko2dc896e2021-08-02 12:03:59 +0000964
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000965 if !flowsFound {
966 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 log.Fields{"device-id": dh.DeviceID})
968 if !dh.IsSkipOnuConfigReconciling() {
969 dh.StopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000970 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 return
972 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 if dh.IsSkipOnuConfigReconciling() {
974 dh.SetDeviceReason(cmn.DrOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000975 }
976}
977
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000978func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.DeviceID})
980 dh.StopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000981}
982
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000987 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000988 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000990 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000991 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992
993 // deadline context to ensure completion of background routines waited for
994 //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 +0530995 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000998 pDevEntry.ResetKvProcessingErrorIndication()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000999
1000 var wg sync.WaitGroup
1001 wg.Add(1) // for the 1 go routine to finish
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 go pDevEntry.DeleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001003 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001005 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001006 return pDevEntry.GetKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001007}
1008
mpagenko15ff4a52021-03-02 10:09:20 +00001009//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1010// before this change here return like this was used:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001011// return fmt.Errorf("device-unreachable: %s, %s", dh.DeviceID, device.SerialNumber)
mpagenko15ff4a52021-03-02 10:09:20 +00001012//was and is called in background - error return does not make sense
1013func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001014 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.DeviceID, "SerialNumber": dh.device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001015 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001017 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001018 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001019 if err := dh.pOnuOmciDevice.Reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301020 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001021 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001022 return
Himani Chawla4d908332020-08-31 12:30:20 +05301023 }
mpagenko01e726e2020-10-23 09:45:29 +00001024
1025 //transfer the possibly modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001026 dh.DisableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001027
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001029 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001030 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001031 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001032 ConnStatus: voltha.ConnectStatus_REACHABLE,
1033 OperStatus: voltha.OperStatus_DISCOVERED,
1034 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001035 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001036 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001037 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001038 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039 if err := dh.deviceReasonUpdate(ctx, cmn.DrRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001040 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001041 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 dh.SetReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001043 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1044 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1045 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1046 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001047}
1048
mpagenkoc8bba412021-01-15 15:38:44 +00001049//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001050// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001051func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 apDownloadManager *swupg.AdapterDownloadManager) error {
mpagenko80622a52021-02-09 16:53:23 +00001053 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001054 "device-id": dh.DeviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001055
1056 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001057 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko15ff4a52021-03-02 10:09:20 +00001058 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001059 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1060 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenko15ff4a52021-03-02 10:09:20 +00001061 }
1062
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001063 if dh.IsReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001064 var inactiveImageID uint16
1065 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1066 dh.lockUpgradeFsm.Lock()
1067 defer dh.lockUpgradeFsm.Unlock()
1068 if dh.pOnuUpradeFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko15ff4a52021-03-02 10:09:20 +00001070 if err == nil {
1071 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1072 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 "device-id": dh.DeviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001074 }
1075 } else {
1076 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001077 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001078 }
mpagenko15ff4a52021-03-02 10:09:20 +00001079 } else { //OnuSw upgrade already running - restart (with possible abort of running)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001080 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
1081 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1082 //no effort spent anymore for the old API to automatically cancel and restart the download
1083 // like done for the new API
1084 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001085 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1086 //no effort spent anymore for the old API to automatically cancel and restart the download
1087 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001088 }
mpagenko15ff4a52021-03-02 10:09:20 +00001089 } else {
1090 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001091 "device-id": dh.DeviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001092 }
1093 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001094 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.DeviceID})
1095 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.DeviceID)
mpagenko80622a52021-02-09 16:53:23 +00001096 }
1097 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001098}
1099
mpagenkoc26d4c02021-05-06 14:27:57 +00001100//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1101// after the OnuImage has been downloaded to the adapter, called in background
1102func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001103 apDownloadManager *swupg.FileDownloadManager, aImageIdentifier string) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001104
1105 var err error
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001106 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001107 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001108 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
mpagenkoc26d4c02021-05-06 14:27:57 +00001109 return
1110 }
1111
1112 var inactiveImageID uint16
1113 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1114 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001115 "device-id": dh.DeviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001116
1117 dh.lockUpgradeFsm.RLock()
1118 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001119 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko38662d02021-08-11 09:45:19 +00001120 dh.lockUpgradeFsm.RUnlock()
1121 if lopOnuUpradeFsm != nil {
1122 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1123 // abort the current processing, running upgrades are always aborted by newer request
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001125 //flush the remove upgradeFsmChan channel
1126 select {
1127 case <-dh.upgradeFsmChan:
1128 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1129 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001130 }
mpagenko38662d02021-08-11 09:45:19 +00001131 lopOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1132 select {
1133 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001134 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001135 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1136 return
1137 case <-dh.upgradeFsmChan:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00001139 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001140 }
mpagenko38662d02021-08-11 09:45:19 +00001141
1142 //here it can be assumed that no running upgrade processing exists (anymore)
1143 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1144 // but none yet defined
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001145 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenko38662d02021-08-11 09:45:19 +00001146 if err == nil {
1147 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1148 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1149 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001151 return
1152 }
mpagenko38662d02021-08-11 09:45:19 +00001153 } else {
1154 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001155 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001156 }
1157 return
1158 }
1159 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001160 "device-id": dh.DeviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001161}
1162
1163//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001164func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1165 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001166 var err error
1167 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1168 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1169 // 2.) activation of the inactive image
1170
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001171 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001172 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001173 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1174 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001175 }
1176 dh.lockUpgradeFsm.RLock()
1177 if dh.pOnuUpradeFsm != nil {
1178 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001179 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001180 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1182 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001183 }
1184 // use the OnuVendor identification from this device for the internal unique name
1185 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001186 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001187 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001188 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001189 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001190 "device-id": dh.DeviceID, "error": err})
1191 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001192 }
mpagenko183647c2021-06-08 15:25:04 +00001193 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001194 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001195 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001196 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001197 } //else
1198 dh.lockUpgradeFsm.RUnlock()
1199
1200 // 2.) check if requested image-version equals the inactive one and start its activation
1201 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1202 var inactiveImageID uint16
1203 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1204 logger.Errorw(ctx, "get inactive image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 "device-id": dh.DeviceID, "err": err, "image-id": inactiveImageID})
1206 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001207 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001208 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoc26d4c02021-05-06 14:27:57 +00001209 if err == nil {
1210 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1211 inactiveImageID, aCommitRequest); err != nil {
1212 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001213 "device-id": dh.DeviceID, "error": err})
1214 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001215 }
1216 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001217 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001218 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001219 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001220 } //else
1221 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001222 "device-id": dh.DeviceID, "error": err})
1223 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001224}
1225
1226//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001227func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1228 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001229 var err error
1230 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1231 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1232 // 2.) commitment of the active image
1233
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkoc26d4c02021-05-06 14:27:57 +00001235 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
1237 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001238 }
1239 dh.lockUpgradeFsm.RLock()
1240 if dh.pOnuUpradeFsm != nil {
1241 dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 if getErr != nil || onuVolthaDevice == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.DeviceID, "err": getErr})
1245 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001246 }
1247 // use the OnuVendor identification from this device for the internal unique name
1248 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001249 // 1.) check a started upgrade process and relay the commitment request to it
1250 // the running upgrade may be based either on the imageIdentifier (started from download)
1251 // or on the imageVersion (started from pure activation)
1252 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1253 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001254 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001255 "device-id": dh.DeviceID, "error": err})
1256 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001257 }
mpagenko183647c2021-06-08 15:25:04 +00001258 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001259 "device-id": dh.DeviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001260 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001261 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001262 } //else
1263 dh.lockUpgradeFsm.RUnlock()
1264
mpagenko183647c2021-06-08 15:25:04 +00001265 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001266 var activeImageID uint16
1267 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1268 logger.Errorw(ctx, "get active image failed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 "device-id": dh.DeviceID, "err": err, "image-id": activeImageID})
1270 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001271 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, cmn.OmciOnuSwUpgradeDone)
mpagenkoc26d4c02021-05-06 14:27:57 +00001273 if err == nil {
1274 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1275 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001276 "device-id": dh.DeviceID, "error": err})
1277 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 }
1279 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 "device-id": dh.DeviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001281 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001282 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001283 } //else
1284 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 "device-id": dh.DeviceID, "error": err})
1286 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.DeviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001287}
1288
mpagenkoaa3afe92021-05-21 16:20:58 +00001289func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001290 aVersion string) *voltha.ImageState {
1291 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001292 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001293 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001294 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001295 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1296 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1297 if aVersion == dh.pLastUpgradeImageState.Version {
1298 pImageState = dh.pLastUpgradeImageState
1299 } else { //state request for an image version different from last processed image version
1300 pImageState = &voltha.ImageState{
1301 Version: aVersion,
1302 //we cannot state something concerning this version
1303 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1304 Reason: voltha.ImageState_NO_ERROR,
1305 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1306 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001307 }
1308 }
mpagenko38662d02021-08-11 09:45:19 +00001309 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001310}
1311
1312func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1313 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 pDeviceImageState.DeviceId = dh.DeviceID
mpagenko7455fd42021-06-10 16:25:55 +00001315 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001316 dh.lockUpgradeFsm.RLock()
1317 if dh.pOnuUpradeFsm != nil {
mpagenko45586762021-10-01 08:30:22 +00001318 dh.lockUpgradeFsm.RUnlock()
1319 // so then we cancel the upgrade operation
1320 // but before we still request the actual upgrade states (which should not change with the cancellation)
1321 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1322 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
1323 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1324 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1325 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1326 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
mpagenko38662d02021-08-11 09:45:19 +00001327 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
mpagenko45586762021-10-01 08:30:22 +00001328 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001329 } else {
mpagenko45586762021-10-01 08:30:22 +00001330 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00001331 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1332 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1333 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1334 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1335 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1336 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001337 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1338 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001339 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1340 //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 +00001341 }
1342}
1343
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001344func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1345
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001346 var onuImageStatus *swupg.OnuImageStatus
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001347
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001348 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001349 if pDevEntry != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 onuImageStatus = swupg.NewOnuImageStatus(dh, pDevEntry)
1351 pDevEntry.MutexOnuImageStatus.Lock()
1352 pDevEntry.POnuImageStatus = onuImageStatus
1353 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001354
1355 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001356 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001357 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1358 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 images, err := onuImageStatus.GetOnuImageStatus(ctx)
1360 pDevEntry.MutexOnuImageStatus.Lock()
1361 pDevEntry.POnuImageStatus = nil
1362 pDevEntry.MutexOnuImageStatus.Unlock()
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001363 return images, err
1364}
1365
Himani Chawla6d2ae152020-09-02 13:11:20 +05301366// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001367// #####################################################################################
1368
1369// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301370// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001371
dbainbri4d3a0dc2020-12-02 00:33:42 +00001372func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001373 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 +00001374}
1375
1376// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001378
dbainbri4d3a0dc2020-12-02 00:33:42 +00001379 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001380 var err error
1381
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001382 // populate what we know. rest comes later after mib sync
1383 dh.device.Root = false
1384 dh.device.Vendor = "OpenONU"
1385 dh.device.Model = "go"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 dh.device.Reason = cmn.DeviceReasonMap[cmn.DrActivatingOnu]
1387 dh.SetDeviceReason(cmn.DrActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001388
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001389 dh.logicalDeviceID = dh.DeviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001390
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 if !dh.IsReconciling() {
1392 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001393 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1394 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1395 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301396 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001397 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001398 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001400 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001401
Himani Chawla4d908332020-08-31 12:30:20 +05301402 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001403 dh.ponPortNumber = dh.device.ParentPortNo
1404
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001405 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1406 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1407 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001408 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.DeviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001409 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301410 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001411
1412 /*
1413 self._pon = PonPort.create(self, self._pon_port_number)
1414 self._pon.add_peer(self.parent_id, self._pon_port_number)
1415 self.logger.debug('adding-pon-port-to-agent',
1416 type=self._pon.get_port().type,
1417 admin_state=self._pon.get_port().admin_state,
1418 oper_status=self._pon.get_port().oper_status,
1419 )
1420 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 if !dh.IsReconciling() {
1422 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.DeviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001423 var ponPortNo uint32 = 1
1424 if dh.ponPortNumber != 0 {
1425 ponPortNo = dh.ponPortNumber
1426 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001427
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001428 pPonPort := &voltha.Port{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001429 DeviceId: dh.DeviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001430 PortNo: ponPortNo,
1431 Label: fmt.Sprintf("pon-%d", ponPortNo),
1432 Type: voltha.Port_PON_ONU,
1433 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301434 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001435 PortNo: ponPortNo}}, // Peer port is parent's port number
1436 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001437 if err = dh.CreatePortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001439 e.Cancel(err)
1440 return
1441 }
1442 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001443 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001444 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001446}
1447
1448// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001450
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001452 var err error
1453 /*
1454 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1455 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1456 return nil
1457 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001458 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1459 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001460 e.Cancel(err)
1461 return
1462 }
1463
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464 if dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001466 // reconcilement will be continued after mib download is done
1467 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001468
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001469 /*
1470 ############################################################################
1471 # Setup Alarm handler
1472 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1473 device.serial_number)
1474 ############################################################################
1475 # Setup PM configuration for this device
1476 # Pass in ONU specific options
1477 kwargs = {
1478 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1479 'heartbeat': self.heartbeat,
1480 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1481 }
1482 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1483 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1484 self.logical_device_id, device.serial_number,
1485 grouped=True, freq_override=False, **kwargs)
1486 pm_config = self._pm_metrics.make_proto()
1487 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1488 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1489 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1490
1491 # Note, ONU ID and UNI intf set in add_uni_port method
1492 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1493 ani_ports=[self._pon])
1494
1495 # Code to Run OMCI Test Action
1496 kwargs_omci_test_action = {
1497 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1498 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1499 }
1500 serial_number = device.serial_number
1501 self._test_request = OmciTestRequest(self.core_proxy,
1502 self.omci_agent, self.device_id,
1503 AniG, serial_number,
1504 self.logical_device_id,
1505 exclusive=False,
1506 **kwargs_omci_test_action)
1507
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 self.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001509 else:
1510 self.logger.info('onu-already-activated')
1511 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001512
dbainbri4d3a0dc2020-12-02 00:33:42 +00001513 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001514}
1515
1516// doStateConnected get the device info and update to voltha core
1517// for comparison of the original method (not that easy to uncomment): compare here:
1518// voltha-openolt-adapter/adaptercore/device_handler.go
1519// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001521
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301523 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001524 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526}
1527
1528// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530
dbainbri4d3a0dc2020-12-02 00:33:42 +00001531 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301532 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001533 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001535
1536 /*
1537 // Synchronous call to update device state - this method is run in its own go routine
1538 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1539 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001540 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 +00001541 return err
1542 }
1543 return nil
1544 */
1545}
1546
1547// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001549
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001551 var err error
1552
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001553 device := dh.device
1554 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001555 /*TODO: needs to handle error scenarios */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001557 e.Cancel(err)
1558 return
1559 }
1560
1561 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001563 /*
1564 // Update the all ports state on that device to disable
1565 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001566 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001567 return er
1568 }
1569
1570 //Update the device oper state and connection status
1571 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1572 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1573 dh.device = cloned
1574
1575 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001576 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001577 return er
1578 }
1579
1580 //get the child device for the parent device
1581 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1582 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001583 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001584 return err
1585 }
1586 for _, onuDevice := range onuDevices.Items {
1587
1588 // Update onu state as down in onu adapter
1589 onuInd := oop.OnuIndication{}
1590 onuInd.OperState = "down"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001591 er := dh.adapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001592 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1593 if er != nil {
1594 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001595 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001596 //Do not return here and continue to process other ONUs
1597 }
1598 }
1599 // * Discovered ONUs entries need to be cleared , since after OLT
1600 // is up, it starts sending discovery indications again* /
1601 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001602 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001603 return nil
1604 */
Himani Chawla4d908332020-08-31 12:30:20 +05301605 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001608}
1609
Himani Chawla6d2ae152020-09-02 13:11:20 +05301610// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611// #################################################################################
1612
1613// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301614// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001616//GetOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
1617func (dh *deviceHandler) GetOnuDeviceEntry(ctx context.Context, aWait bool) *mib.OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001618 dh.lockDevice.RLock()
1619 pOnuDeviceEntry := dh.pOnuOmciDevice
1620 if aWait && pOnuDeviceEntry == nil {
1621 //keep the read sema short to allow for subsequent write
1622 dh.lockDevice.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001624 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1625 // so it might be needed to wait here for that event with some timeout
1626 select {
1627 case <-time.After(60 * time.Second): //timer may be discussed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001629 return nil
1630 case <-dh.deviceEntrySet:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001632 // if written now, we can return the written value without sema
1633 return dh.pOnuOmciDevice
1634 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001635 }
mpagenko3af1f032020-06-10 08:53:41 +00001636 dh.lockDevice.RUnlock()
1637 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001638}
1639
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640//setDeviceHandlerEntries sets the ONU device entry within the handler
1641func (dh *deviceHandler) setDeviceHandlerEntries(apDeviceEntry *mib.OnuDeviceEntry, apOnuTp *avcfg.OnuUniTechProf,
1642 apOnuMetricsMgr *pmmgr.OnuMetricsManager, apOnuAlarmMgr *almgr.OnuAlarmManager, apSelfTestHdlr *otst.SelfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001643 dh.lockDevice.Lock()
1644 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001645 dh.pOnuOmciDevice = apDeviceEntry
1646 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001647 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301648 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001649 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001650}
1651
Himani Chawla6d2ae152020-09-02 13:11:20 +05301652//addOnuDeviceEntry creates a new ONU device or returns the existing
1653func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001656 deviceEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001657 if deviceEntry == nil {
1658 /* costum_me_map in python code seems always to be None,
1659 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1660 /* also no 'clock' argument - usage open ...*/
1661 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 deviceEntry = mib.NewOnuDeviceEntry(ctx, dh.coreClient, dh, dh.pOpenOnuAc)
1663 onuTechProfProc := avcfg.NewOnuUniTechProf(ctx, dh, deviceEntry)
1664 onuMetricsMgr := pmmgr.NewOnuMetricsManager(ctx, dh, deviceEntry)
1665 onuAlarmManager := almgr.NewAlarmManager(ctx, dh, deviceEntry)
1666 selfTestHdlr := otst.NewSelfTestMsgHandlerCb(ctx, dh, deviceEntry)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667 //error treatment possible //TODO!!!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 dh.setDeviceHandlerEntries(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001669 // fire deviceEntry ready event to spread to possibly waiting processing
1670 dh.deviceEntrySet <- true
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001671 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001672 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001674 }
1675 // might be updated with some error handling !!!
1676 return nil
1677}
1678
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1680 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001681 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1682
1683 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001684
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001686 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
1688 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001689 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001690 if !dh.IsReconciling() {
1691 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001693 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001694 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001696 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001697
1698 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001700 OperStatus: voltha.OperStatus_ACTIVATING,
1701 ConnStatus: voltha.ConnectStatus_REACHABLE,
1702 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001703 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001704 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001705 }
1706 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001708 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001709
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001710 pDevEntry.MutexPersOnuConfig.RLock()
1711 if !pDevEntry.SOnuPersistentData.PersUniUnlockDone {
1712 pDevEntry.MutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 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 +00001714 log.Fields{"device-id": dh.DeviceID})
1715 dh.StopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001716 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001717 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001718 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001720 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1721 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1722 // 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 +00001723 // 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 +00001724 // so let's just try to keep it simple ...
1725 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001727 if err != nil || device == nil {
1728 //TODO: needs to handle error scenarios
1729 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1730 return errors.New("Voltha Device not found")
1731 }
1732 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001733
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001734 if err := pDevEntry.Start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001735 return err
mpagenko3af1f032020-06-10 08:53:41 +00001736 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001737
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001738 _ = dh.deviceReasonUpdate(ctx, cmn.DrStartingOpenomci, !dh.IsReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001739
1740 /* this might be a good time for Omci Verify message? */
1741 verifyExec := make(chan bool)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001742 omciVerify := otst.NewOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001743 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001744 true, true) //exclusive and allowFailure (anyway not yet checked)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 omciVerify.PerformOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001746
1747 /* give the handler some time here to wait for the OMCi verification result
1748 after Timeout start and try MibUpload FSM anyway
1749 (to prevent stopping on just not supported OMCI verification from ONU) */
1750 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001751 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001755 }
1756
1757 /* In py code it looks earlier (on activate ..)
1758 # Code to Run OMCI Test Action
1759 kwargs_omci_test_action = {
1760 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1761 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1762 }
1763 serial_number = device.serial_number
1764 self._test_request = OmciTestRequest(self.core_proxy,
1765 self.omci_agent, self.device_id,
1766 AniG, serial_number,
1767 self.logical_device_id,
1768 exclusive=False,
1769 **kwargs_omci_test_action)
1770 ...
1771 # Start test requests after a brief pause
1772 if not self._test_request_started:
1773 self._test_request_started = True
1774 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1775 reactor.callLater(tststart, self._test_request.start_collector)
1776
1777 */
1778 /* which is then: in omci_test_request.py : */
1779 /*
1780 def start_collector(self, callback=None):
1781 """
1782 Start the collection loop for an adapter if the frequency > 0
1783
1784 :param callback: (callable) Function to call to collect PM data
1785 """
1786 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1787 if callback is None:
1788 callback = self.perform_test_omci
1789
1790 if self.lc is None:
1791 self.lc = LoopingCall(callback)
1792
1793 if self.default_freq > 0:
1794 self.lc.start(interval=self.default_freq / 10)
1795
1796 def perform_test_omci(self):
1797 """
1798 Perform the initial test request
1799 """
1800 ani_g_entities = self._device.configuration.ani_g_entities
1801 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1802 is not None else None
1803 self._entity_id = ani_g_entities_ids[0]
1804 self.logger.info('perform-test', entity_class=self._entity_class,
1805 entity_id=self._entity_id)
1806 try:
1807 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1808 result = yield self._device.omci_cc.send(frame)
1809 if not result.fields['omci_message'].fields['success_code']:
1810 self.logger.info('Self-Test Submitted Successfully',
1811 code=result.fields[
1812 'omci_message'].fields['success_code'])
1813 else:
1814 raise TestFailure('Test Failure: {}'.format(
1815 result.fields['omci_message'].fields['success_code']))
1816 except TimeoutError as e:
1817 self.deferred.errback(failure.Failure(e))
1818
1819 except Exception as e:
1820 self.logger.exception('perform-test-Error', e=e,
1821 class_id=self._entity_class,
1822 entity_id=self._entity_id)
1823 self.deferred.errback(failure.Failure(e))
1824
1825 */
1826
1827 // PM related heartbeat??? !!!TODO....
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001828 //self._heartbeat.Enabled = True
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829
mpagenko1cc3cb42020-07-27 15:24:38 +00001830 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1831 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1832 * 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 +05301833 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001834 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 //call MibUploadFSM - transition up to state UlStInSync
1836 pMibUlFsm := pDevEntry.PMibUploadFsm.PFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001837 if pMibUlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 if pMibUlFsm.Is(mib.UlStDisabled) {
1839 if err := pMibUlFsm.Event(mib.UlEvStart); err != nil {
1840 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.DeviceID, "err": err})
1841 return fmt.Errorf("can't go to state starting: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301842 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301844 //Determine ONU status and start/re-start MIB Synchronization tasks
1845 //Determine if this ONU has ever synchronized
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001846 if pDevEntry.IsNewOnu() {
1847 if err := pMibUlFsm.Event(mib.UlEvResetMib); err != nil {
1848 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.DeviceID, "err": err})
1849 return fmt.Errorf("can't go to state resetting_mib: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001850 }
Himani Chawla4d908332020-08-31 12:30:20 +05301851 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 if err := pMibUlFsm.Event(mib.UlEvExamineMds); err != nil {
1853 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.DeviceID, "err": err})
1854 return fmt.Errorf("can't go to examine_mds: %s", dh.DeviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301855 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001856 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001857 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001858 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001860 "device-id": dh.DeviceID})
1861 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001862 }
1863 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001864 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
1865 return fmt.Errorf("can't execute MibSync: %s", dh.DeviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001866 }
1867 return nil
1868}
1869
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001871 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001872 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001873 if dh.getDeviceReason() != cmn.DrStoppingOpenomci {
1874 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.DeviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001875
mpagenko900ee4b2020-10-12 11:56:34 +00001876 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1877 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1878 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001879 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001880 logger.Errorw(ctx, "error-updateInterface at FSM stop",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001881 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001882 // abort: system behavior is just unstable ...
1883 return err
1884 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001885 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 _ = 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 +00001887
1888 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1889 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1890 //stop the device entry which resets the attached omciCC
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001891 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001892 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001893 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
1894 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001895 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001896 _ = pDevEntry.Stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001897
1898 //TODO!!! remove existing traffic profiles
1899 /* from py code, if TP's exist, remove them - not yet implemented
1900 self._tp = dict()
1901 # Let TP download happen again
1902 for uni_id in self._tp_service_specific_task:
1903 self._tp_service_specific_task[uni_id].clear()
1904 for uni_id in self._tech_profile_download_done:
1905 self._tech_profile_download_done[uni_id].clear()
1906 */
1907
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001908 dh.DisableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001909
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001910 dh.SetReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001911
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001912 if err := dh.deviceReasonUpdate(ctx, cmn.DrStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001913 // abort: system behavior is just unstable ...
1914 return err
1915 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001917 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001918 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001919 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04001920 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
1921 OperStatus: voltha.OperStatus_DISCOVERED,
1922 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001923 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001925 log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001926 // abort: system behavior is just unstable ...
1927 return err
1928 }
1929 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001930 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001931 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001932 return nil
1933}
1934
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001935func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001936 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1937 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1938 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1939 // and using the stop/reset event should never harm
1940
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001941 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001942 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001943 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
1944 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
mpagenko900ee4b2020-10-12 11:56:34 +00001945 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001946 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00001947 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001948 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001949 pDevEntry.MutexOnuImageStatus.RLock()
1950 if pDevEntry.POnuImageStatus != nil {
1951 pDevEntry.POnuImageStatus.CancelProcessing(ctx)
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001952 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 pDevEntry.MutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001954
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001955 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001956 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001957 }
1958 //MibDownload may run
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001959 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
mpagenko900ee4b2020-10-12 11:56:34 +00001960 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 _ = pMibDlFsm.Event(mib.DlEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00001962 }
1963 //port lock/unlock FSM's may be active
1964 if dh.pUnlockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00001966 }
1967 if dh.pLockStateFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
mpagenko900ee4b2020-10-12 11:56:34 +00001969 }
1970 //techProfile related PonAniConfigFsm FSM may be active
1971 if dh.pOnuTP != nil {
1972 // should always be the case here
1973 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 if dh.pOnuTP.PAniConfigFsm != nil {
1975 for uniTP := range dh.pOnuTP.PAniConfigFsm {
1976 dh.pOnuTP.PAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001977 }
mpagenko900ee4b2020-10-12 11:56:34 +00001978 }
1979 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001980 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001981 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.UniID]; exist {
mpagenko900ee4b2020-10-12 11:56:34 +00001983 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001984 dh.lockVlanConfig.RUnlock()
1985 //reset of all Fsm is always accompanied by global persistency data removal
1986 // no need to remove specific data
1987 pVlanFilterFsm.RequestClearPersistency(false)
1988 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001989 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001990 } else {
1991 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001992 }
1993 }
1994 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001995 if dh.GetCollectorIsRunning() {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001996 // Stop collector routine
1997 dh.stopCollector <- true
1998 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001999 if dh.GetAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302000 dh.stopAlarmManager <- true
2001 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002002 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002003 dh.pSelfTestHdlr.StopSelfTestModule <- true
Girish Gowdra10123c02021-08-30 11:52:06 -07002004 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302005
mpagenko80622a52021-02-09 16:53:23 +00002006 //reset a possibly running upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002007 // (note the Upgrade FSM may stay alive e.g. in state UpgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002008 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002009 lopOnuUpradeFsm := dh.pOnuUpradeFsm
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002010 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002011 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002012 if lopOnuUpradeFsm != nil {
2013 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2014 }
mpagenko80622a52021-02-09 16:53:23 +00002015
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002016 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002017 return nil
2018}
2019
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002020func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2021 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 +05302022
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002023 // store persistent data collected during MIB upload processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002024 if err := dh.StorePersistentData(ctx); err != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002025 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002026 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002027 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002028 _ = dh.deviceReasonUpdate(ctx, cmn.DrDiscoveryMibsyncComplete, !dh.IsReconciling())
2029 dh.AddAllUniPorts(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002030
mpagenkoa40e99a2020-11-17 13:50:39 +00002031 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2032 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2033 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2034 * disable/enable toggling here to allow traffic
2035 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2036 * like the py comment says:
2037 * # start by locking all the unis till mib sync and initial mib is downloaded
2038 * # this way we can capture the port down/up events when we are ready
2039 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302040
mpagenkoa40e99a2020-11-17 13:50:39 +00002041 // Init Uni Ports to Admin locked state
2042 // *** should generate UniLockStateDone event *****
2043 if dh.pLockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002044 dh.createUniLockFsm(ctx, true, cmn.UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002045 } else { //LockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002046 dh.pLockStateFsm.SetSuccessEvent(cmn.UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002048 }
2049}
2050
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002051func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2052 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302053 /* Mib download procedure -
2054 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2055 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002056 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002057 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002058 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002059 return
2060 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002061 pMibDlFsm := pDevEntry.PMibDownloadFsm.PFsm
Himani Chawla26e555c2020-08-31 12:30:20 +05302062 if pMibDlFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002063 if pMibDlFsm.Is(mib.DlStDisabled) {
2064 if err := pMibDlFsm.Event(mib.DlEvStart); err != nil {
2065 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 +05302066 // maybe try a FSM reset and then again ... - TODO!!!
2067 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302069 // maybe use more specific states here for the specific download steps ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002070 if err := pMibDlFsm.Event(mib.DlEvCreateGal); err != nil {
2071 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.DeviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302072 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302074 //Begin MIB data download (running autonomously)
2075 }
2076 }
2077 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002079 "device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302080 // maybe try a FSM reset and then again ... - TODO!!!
2081 }
2082 /***** Mib download started */
2083 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002084 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302085 }
2086}
2087
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002088func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2089 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302090 //initiate DevStateUpdate
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002091 if !dh.IsReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002093 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002094 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2095 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2096 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2097 dh.checkOnOnuImageCommit(ctx)
khenaidoo7d3c5582021-08-11 18:09:44 -04002098 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002099 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002100 ConnStatus: voltha.ConnectStatus_REACHABLE,
2101 OperStatus: voltha.OperStatus_ACTIVE,
2102 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302103 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002104 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302105 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002106 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302107 }
2108 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002110 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302111 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002112 _ = dh.deviceReasonUpdate(ctx, cmn.DrInitialMibDownloaded, !dh.IsReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002113
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002114 if !dh.GetCollectorIsRunning() {
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002115 // Start PM collector routine
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002116 go dh.StartCollector(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002117 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002118 if !dh.GetAlarmManagerIsRunning(ctx) {
2119 go dh.StartAlarmManager(ctx)
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002120 }
2121
Girish Gowdrae0140f02021-02-02 16:55:09 -08002122 // Initialize classical L2 PM Interval Counters
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002123 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventInit); err != nil {
Girish Gowdrae0140f02021-02-02 16:55:09 -08002124 // There is no way we should be landing here, but if we do then
2125 // there is nothing much we can do about this other than log error
2126 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2127 }
2128
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002129 dh.SetReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002130
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002131 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002132 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002133 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002134 return
2135 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002136 pDevEntry.MutexPersOnuConfig.RLock()
2137 if dh.IsReconciling() && pDevEntry.SOnuPersistentData.PersUniDisableDone {
2138 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002139 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 log.Fields{"device-id": dh.DeviceID})
2141 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002142 // reconcilement will be continued after ani config is done
2143 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002144 pDevEntry.MutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002145 // *** should generate UniUnlockStateDone event *****
2146 if dh.pUnlockStateFsm == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002147 dh.createUniLockFsm(ctx, false, cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002148 } else { //UnlockStateFSM already init
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002149 dh.pUnlockStateFsm.SetSuccessEvent(cmn.UniUnlockStateDone)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002150 dh.runUniLockFsm(ctx, false)
2151 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302152 }
2153}
2154
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002155func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2156 dh.EnableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302157
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002158 if !dh.IsReconciling() {
2159 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002160 raisedTs := time.Now().Unix()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002161 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.DeviceID, raisedTs) //cmp python onu_active_event
2162 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002163 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002164 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002165 return
2166 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002167 pDevEntry.MutexPersOnuConfig.Lock()
2168 pDevEntry.SOnuPersistentData.PersUniUnlockDone = true
2169 pDevEntry.MutexPersOnuConfig.Unlock()
2170 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002172 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002173 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302174 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 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 +00002176 log.Fields{"device-id": dh.DeviceID})
2177 go dh.ReconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002178 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302179 }
2180}
2181
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002185
2186 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002187 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002188 ConnStatus: voltha.ConnectStatus_REACHABLE,
2189 OperStatus: voltha.OperStatus_UNKNOWN,
2190 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002191 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002193 }
2194
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": cmn.DeviceReasonMap[cmn.DrOmciAdminLock], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002196 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002198
2199 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002200 dh.DisableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002201
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002202 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002203 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002204 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002205 return
2206 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002207 pDevEntry.MutexPersOnuConfig.Lock()
2208 pDevEntry.SOnuPersistentData.PersUniDisableDone = true
2209 pDevEntry.MutexPersOnuConfig.Unlock()
2210 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002213 }
mpagenko900ee4b2020-10-12 11:56:34 +00002214}
2215
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002219 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002220 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002221 ConnStatus: voltha.ConnectStatus_REACHABLE,
2222 OperStatus: voltha.OperStatus_ACTIVE,
2223 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002224 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.DeviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002226 }
2227
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002229 "reason": cmn.DeviceReasonMap[cmn.DrOnuReenabled], "device-id": dh.DeviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002230 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 _ = dh.deviceReasonUpdate(ctx, cmn.DrOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002232
2233 //transfer the modified logical uni port state
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002234 dh.EnableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002235
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002236 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002237 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002239 return
2240 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002241 pDevEntry.MutexPersOnuConfig.Lock()
2242 pDevEntry.SOnuPersistentData.PersUniDisableDone = false
2243 pDevEntry.MutexPersOnuConfig.Unlock()
2244 if err := dh.StorePersistentData(ctx); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002245 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 log.Fields{"device-id": dh.DeviceID, "err": err})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002247 }
mpagenko900ee4b2020-10-12 11:56:34 +00002248}
2249
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
2251 if devEvent == cmn.OmciAniConfigDone {
2252 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002253 // attention: the device reason update is done based on ONU-UNI-Port related activity
2254 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002255 if dh.getDeviceReason() != cmn.DrTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002256 // 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 +00002257 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDownloadSuccess, !dh.IsReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302258 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002259 if dh.IsReconciling() {
2260 go dh.ReconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002261 }
2262 } else { // should be the OmciAniResourceRemoved block
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.DeviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002264 // attention: the device reason update is done based on ONU-UNI-Port related activity
2265 // - which may cause some inconsistency
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002266 if dh.getDeviceReason() != cmn.DrTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002267 // 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 +00002268 _ = dh.deviceReasonUpdate(ctx, cmn.DrTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002269 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002270 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302271}
2272
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002273func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent cmn.OnuDeviceEvent) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002274 logger.Debugw(ctx, "OmciVlanFilterDone event received",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 log.Fields{"device-id": dh.DeviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302276 // attention: the device reason update is done based on ONU-UNI-Port related activity
2277 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302278
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002279 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterAddDoneNoKvStore {
2280 if dh.getDeviceReason() != cmn.DrOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002281 // which may be the case from some previous actvity on another UNI Port of the ONU
2282 // or even some previous flow add activity on the same port
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002283 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsPushed, !dh.IsReconciling())
2284 if dh.IsReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002285 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002286 }
2287 }
2288 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 if dh.getDeviceReason() != cmn.DrOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002290 //not relevant for reconcile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291 _ = dh.deviceReasonUpdate(ctx, cmn.DrOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002292 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302293 }
mpagenkof1fc3862021-02-16 10:09:52 +00002294
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002295 if aDevEvent == cmn.OmciVlanFilterAddDone || aDevEvent == cmn.OmciVlanFilterRemDone {
mpagenkof1fc3862021-02-16 10:09:52 +00002296 //events that request KvStore write
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002297 if err := dh.StorePersistentData(ctx); err != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002298 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002299 log.Fields{"device-id": dh.DeviceID, "err": err})
mpagenkof1fc3862021-02-16 10:09:52 +00002300 }
2301 } else {
2302 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002303 log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002304 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302305}
2306
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002307//DeviceProcStatusUpdate evaluates possible processing events and initiates according next activities
2308func (dh *deviceHandler) DeviceProcStatusUpdate(ctx context.Context, devEvent cmn.OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302309 switch devEvent {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002310 case cmn.MibDatabaseSync:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002311 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002313 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 case cmn.UniLockStateDone:
mpagenkoa40e99a2020-11-17 13:50:39 +00002315 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002316 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002317 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002318 case cmn.MibDownloadDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002319 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002321 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 case cmn.UniUnlockStateDone:
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002323 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002325 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002326 case cmn.UniEnableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002327 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002329 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002330 case cmn.UniDisableStateDone:
mpagenko900ee4b2020-10-12 11:56:34 +00002331 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002333 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 case cmn.OmciAniConfigDone, cmn.OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002335 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002337 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002338 case cmn.OmciVlanFilterAddDone, cmn.OmciVlanFilterAddDoneNoKvStore, cmn.OmciVlanFilterRemDone, cmn.OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002339 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002341 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002342 default:
2343 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.DeviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002345 }
2346 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002347}
2348
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002349func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType cmn.UniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002350 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002351 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302352 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002353 if _, present := dh.uniEntityMap[uniNo]; present {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 logger.Warnw(ctx, "OnuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002355 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302356 //with arguments aUniID, a_portNo, aPortType
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357 pUniPort := cmn.NewOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002358 if pUniPort == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002359 logger.Warnw(ctx, "OnuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002360 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002361 //store UniPort with the System-PortNumber key
2362 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002363 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002364 // create announce the UniPort to the core as VOLTHA Port object
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002365 if err := pUniPort.CreateVolthaPort(ctx, dh); err == nil {
2366 logger.Infow(ctx, "OnuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002367 } //error logging already within UniPort method
2368 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002369 logger.Debugw(ctx, "reconciling - OnuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002370 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002371 }
2372 }
2373}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002374
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375func (dh *deviceHandler) AddAllUniPorts(ctx context.Context) {
2376 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002377 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002379 return
2380 }
2381 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002382 if pptpInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002383 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2384 for _, mgmtEntityID := range pptpInstKeys {
2385 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 "device-id": dh.DeviceID, "PPTPEthUni EntityID": mgmtEntityID})
2387 dh.addUniPort(ctx, mgmtEntityID, i, cmn.UniPPTP)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002388 i++
2389 }
2390 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002392 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 if veipInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002394 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2395 for _, mgmtEntityID := range veipInstKeys {
2396 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002397 "device-id": dh.DeviceID, "VEIP EntityID": mgmtEntityID})
2398 dh.addUniPort(ctx, mgmtEntityID, i, cmn.UniVEIP)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002399 i++
2400 }
2401 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002402 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002403 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002404 if potsInstKeys := pDevEntry.GetOnuDB().GetSortedInstKeys(
ozgecanetsia124d9732021-09-16 14:31:57 +03002405 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2406 for _, mgmtEntityID := range potsInstKeys {
2407 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002408 "device-id": dh.DeviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
2409 dh.addUniPort(ctx, mgmtEntityID, i, cmn.UniPPTPPots)
ozgecanetsia124d9732021-09-16 14:31:57 +03002410 i++
2411 }
2412 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002413 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.DeviceID})
ozgecanetsia124d9732021-09-16 14:31:57 +03002414 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002415 if i == 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002416 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002417 }
2418}
2419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420// EnableUniPortStateUpdate enables UniPortState and update core port state accordingly
2421func (dh *deviceHandler) EnableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002422 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302423 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002424 // with following remark:
2425 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2426 // # load on the core
2427
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002428 // 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 +00002429
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002430 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002431 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002432 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2433 logger.Infow(ctx, "OnuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2434 uniPort.SetOperState(vc.OperStatus_ACTIVE)
2435 if !dh.IsReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002436 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002437 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002438 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002439 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002440 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002441 PortNo: port.PortNo,
2442 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002443 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002444 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 -04002445 }
2446 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002447 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002448 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002449 }
mpagenko3af1f032020-06-10 08:53:41 +00002450 }
2451 }
2452}
2453
2454// Disable UniPortState and update core port state accordingly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002455func (dh *deviceHandler) DisableUniPortStateUpdate(ctx context.Context) {
2456 // compare EnableUniPortStateUpdate() above
mpagenko3af1f032020-06-10 08:53:41 +00002457 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2458 for uniNo, uniPort := range dh.uniEntityMap {
2459 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002460
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 if (1<<uniPort.UniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.UniID) {
2462 logger.Infow(ctx, "OnuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.DeviceID})
2463 uniPort.SetOperState(vc.OperStatus_UNKNOWN)
2464 if !dh.IsReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002465 //maybe also use getter functions on uniPort - perhaps later ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 go func(port *cmn.OnuUniPort) {
khenaidoo7d3c5582021-08-11 18:09:44 -04002467 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04002469 PortType: voltha.Port_ETHERNET_UNI,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 PortNo: port.PortNo,
2471 OperStatus: port.OperState,
khenaidoo7d3c5582021-08-11 18:09:44 -04002472 }); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 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 -04002474 }
2475 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002476 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002477 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002478 }
2479
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002480 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002481 }
2482}
2483
2484// ONU_Active/Inactive announcement on system KAFKA bus
2485// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002486func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002487 var de voltha.DeviceEvent
2488 eventContext := make(map[string]string)
2489 //Populating event context
2490 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002491 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002492 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302494 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002495 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 +00002496 }
2497 oltSerialNumber := parentDevice.SerialNumber
2498
2499 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2500 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2501 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302502 eventContext["olt-serial-number"] = oltSerialNumber
2503 eventContext["device-id"] = aDeviceID
2504 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002505 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002506 if deviceEntry := dh.GetOnuDeviceEntry(ctx, false); deviceEntry != nil {
2507 deviceEntry.MutexPersOnuConfig.RLock()
2508 eventContext["equipment-id"] = deviceEntry.SOnuPersistentData.PersEquipmentID
2509 deviceEntry.MutexPersOnuConfig.RUnlock()
2510 eventContext["software-version"] = deviceEntry.GetActiveImageVersion(ctx)
2511 deviceEntry.MutexPersOnuConfig.RLock()
2512 eventContext["vendor"] = deviceEntry.SOnuPersistentData.PersVendorID
2513 deviceEntry.MutexPersOnuConfig.RUnlock()
2514 eventContext["inactive-software-version"] = deviceEntry.GetInactiveImageVersion(ctx)
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002515 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2516 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2517 } else {
2518 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2519 log.Fields{"device-id": aDeviceID})
2520 return
2521 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002522
2523 /* Populating device event body */
2524 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302525 de.ResourceId = aDeviceID
2526 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002527 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2528 de.Description = fmt.Sprintf("%s Event - %s - %s",
2529 cEventObjectType, cOnuActivatedEvent, "Raised")
2530 } else {
2531 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2532 de.Description = fmt.Sprintf("%s Event - %s - %s",
2533 cEventObjectType, cOnuActivatedEvent, "Cleared")
2534 }
2535 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2537 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302538 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002539 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302541 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002542}
2543
Himani Chawla4d908332020-08-31 12:30:20 +05302544// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent cmn.OnuDeviceEvent) {
2546 chLSFsm := make(chan cmn.Message, 2048)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002547 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302548 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002549 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002550 sFsmName = "LockStateFSM"
2551 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002553 sFsmName = "UnLockStateFSM"
2554 }
mpagenko3af1f032020-06-10 08:53:41 +00002555
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002557 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002559 return
2560 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 pLSFsm := uniprt.NewLockStateFsm(ctx, aAdminState, devEvent, sFsmName, dh, pDevEntry, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002562 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302563 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002564 dh.pLockStateFsm = pLSFsm
2565 } else {
2566 dh.pUnlockStateFsm = pLSFsm
2567 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002569 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002570 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002571 }
2572}
2573
2574// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002575func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002576 /* Uni Port lock/unlock procedure -
2577 ***** should run via 'adminDone' state and generate the argument requested event *****
2578 */
2579 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302580 if aAdminState {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002581 pLSStatemachine = dh.pLockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002582 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2583 if (dh.pUnlockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002584 (dh.pUnlockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2585 _ = dh.pUnlockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002586 }
2587 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002588 pLSStatemachine = dh.pUnlockStateFsm.PAdaptFsm.PFsm
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002589 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2590 if (dh.pLockStateFsm != nil) &&
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002591 (dh.pLockStateFsm.PAdaptFsm.PFsm.Current() != uniprt.UniStDisabled) {
2592 _ = dh.pLockStateFsm.PAdaptFsm.PFsm.Event(uniprt.UniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002593 }
2594 }
2595 if pLSStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 if pLSStatemachine.Is(uniprt.UniStDisabled) {
2597 if err := pLSStatemachine.Event(uniprt.UniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002598 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002599 // maybe try a FSM reset and then again ... - TODO!!!
2600 } else {
2601 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 "state": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002604 }
2605 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002606 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 "have": pLSStatemachine.Current(), "device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002608 // maybe try a FSM reset and then again ... - TODO!!!
2609 }
2610 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002612 // maybe try a FSM reset and then again ... - TODO!!!
2613 }
2614}
2615
mpagenko80622a52021-02-09 16:53:23 +00002616// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002617func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *mib.OnuDeviceEntry, aDevEvent cmn.OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002618 //in here lockUpgradeFsm is already locked
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002619 chUpgradeFsm := make(chan cmn.Message, 2048)
mpagenko80622a52021-02-09 16:53:23 +00002620 var sFsmName = "OnuSwUpgradeFSM"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002622 if apDevEntry.PDevOmciCC == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002623 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002624 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002625 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002626 dh.pOnuUpradeFsm = swupg.NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.GetOnuDB(), aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002627 sFsmName, chUpgradeFsm)
2628 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00002630 if pUpgradeStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002631 if pUpgradeStatemachine.Is(swupg.UpgradeStDisabled) {
2632 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvStart); err != nil {
mpagenko80622a52021-02-09 16:53:23 +00002633 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2634 // maybe try a FSM reset and then again ... - TODO!!!
2635 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2636 }
2637 /***** LockStateFSM started */
mpagenko45586762021-10-01 08:30:22 +00002638 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2639 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
mpagenko38662d02021-08-11 09:45:19 +00002640 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2641 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002642 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002644 } else {
2645 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 "have": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002647 // maybe try a FSM reset and then again ... - TODO!!!
2648 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2649 }
2650 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002651 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002652 // maybe try a FSM reset and then again ... - TODO!!!
2653 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2654 }
2655 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002657 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2658 }
2659 return nil
2660}
2661
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002662// RemoveOnuUpgradeFsm clears the Onu Software upgrade FSM
2663func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002664 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002665 "device-id": dh.DeviceID})
mpagenko80622a52021-02-09 16:53:23 +00002666 dh.lockUpgradeFsm.Lock()
mpagenko80622a52021-02-09 16:53:23 +00002667 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
mpagenko38662d02021-08-11 09:45:19 +00002668 dh.pLastUpgradeImageState = apImageState
2669 dh.lockUpgradeFsm.Unlock()
2670 //signal upgradeFsm removed using non-blocking channel send
2671 select {
2672 case dh.upgradeFsmChan <- struct{}{}:
2673 default:
2674 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002676 }
mpagenko80622a52021-02-09 16:53:23 +00002677}
2678
mpagenko15ff4a52021-03-02 10:09:20 +00002679// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2680func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002681 pDevEntry := dh.GetOnuDeviceEntry(ctx, false)
mpagenko15ff4a52021-03-02 10:09:20 +00002682 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002683 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002684 return
2685 }
2686
2687 dh.lockUpgradeFsm.RLock()
2688 defer dh.lockUpgradeFsm.RUnlock()
2689 if dh.pOnuUpradeFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 pUpgradeStatemachine := dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko15ff4a52021-03-02 10:09:20 +00002691 if pUpgradeStatemachine != nil {
2692 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2693 // (some manual forced commit could do without)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 UpgradeState := pUpgradeStatemachine.Current()
2695 if (UpgradeState == swupg.UpgradeStWaitForCommit) ||
2696 (UpgradeState == swupg.UpgradeStRequestingActivate) {
2697 // also include UpgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002698 // 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 +00002699 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.InactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002700 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2701 if errImg != nil {
2702 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002704 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002705 return
2706 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 if activeImageID == dh.pOnuUpradeFsm.InactiveImageMeID {
2708 if (UpgradeState == swupg.UpgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
mpagenko1f8e8822021-06-25 14:10:21 +00002709 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002710 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvActivationDone); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002711 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2712 return
2713 }
2714 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002716 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002717 //FSM in waitForCommit or (UpgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2718 if err := pUpgradeStatemachine.Event(swupg.UpgradeEvCommitSw); err != nil {
mpagenko1f8e8822021-06-25 14:10:21 +00002719 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2720 return
2721 }
2722 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 "state": UpgradeState, "device-id": dh.DeviceID})
mpagenko1f8e8822021-06-25 14:10:21 +00002724 }
2725 } else {
2726 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 +00002727 log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002728 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko1f8e8822021-06-25 14:10:21 +00002729 return
2730 }
mpagenko15ff4a52021-03-02 10:09:20 +00002731 } else {
2732 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 log.Fields{"device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002734 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002735 return
2736 }
mpagenko183647c2021-06-08 15:25:04 +00002737 } else {
2738 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2739 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2740 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002741 if dh.pOnuUpradeFsm.InactiveImageMeID == activeImageID {
mpagenko183647c2021-06-08 15:25:04 +00002742 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002743 "state": pUpgradeStatemachine.Current(), "device-id": dh.DeviceID})
mpagenko38662d02021-08-11 09:45:19 +00002744 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002745 }
2746 }
mpagenko15ff4a52021-03-02 10:09:20 +00002747 }
2748 }
2749 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.DeviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002751 }
2752}
2753
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754//SetBackend provides a DB backend for the specified path on the existing KV client
2755func (dh *deviceHandler) SetBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002756
2757 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 "BasePathKvStore": aBasePathKvStore, "device-id": dh.DeviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002759 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002760 kvbackend := &db.Backend{
2761 Client: dh.pOpenOnuAc.kvClient,
2762 StoreType: dh.pOpenOnuAc.KVStoreType,
2763 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002764 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002765 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2766 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002767
mpagenkoaf801632020-07-03 10:00:42 +00002768 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002769}
khenaidoo7d3c5582021-08-11 18:09:44 -04002770func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302771 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002772
mpagenkodff5dda2020-08-28 11:52:01 +00002773 for _, field := range flow.GetOfbFields(apFlowItem) {
2774 switch field.Type {
2775 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2776 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002778 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2779 }
mpagenko01e726e2020-10-23 09:45:29 +00002780 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002781 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2782 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302783 *loIPProto = field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002784 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302785 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2786 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002787 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2788 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002789 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002790 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302791 return
mpagenkodff5dda2020-08-28 11:52:01 +00002792 }
2793 }
mpagenko01e726e2020-10-23 09:45:29 +00002794 */
mpagenkodff5dda2020-08-28 11:52:01 +00002795 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2796 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302797 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002798 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302799 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002800 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302801 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002802 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302804 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002805 }
2806 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2807 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302808 *loAddPcp = uint8(field.GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002809 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002810 "PCP": loAddPcp})
2811 }
2812 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2813 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002814 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002815 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2816 }
2817 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2818 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002820 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2821 }
2822 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2823 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002824 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002825 "IPv4-DST": field.GetIpv4Dst()})
2826 }
2827 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2828 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002829 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002830 "IPv4-SRC": field.GetIpv4Src()})
2831 }
2832 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2833 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002835 "Metadata": field.GetTableMetadata()})
2836 }
2837 /*
2838 default:
2839 {
2840 //all other entires ignored
2841 }
2842 */
2843 }
2844 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302845}
mpagenkodff5dda2020-08-28 11:52:01 +00002846
khenaidoo7d3c5582021-08-11 18:09:44 -04002847func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002848 for _, action := range flow.GetActions(apFlowItem) {
2849 switch action.Type {
2850 /* not used:
2851 case of.OfpActionType_OFPAT_OUTPUT:
2852 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 logger.Debugw("flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002854 "Output": action.GetOutput()})
2855 }
2856 */
2857 case of.OfpActionType_OFPAT_PUSH_VLAN:
2858 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002860 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2861 }
2862 case of.OfpActionType_OFPAT_SET_FIELD:
2863 {
2864 pActionSetField := action.GetSetField()
2865 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002867 "OxcmClass": pActionSetField.Field.OxmClass})
2868 }
2869 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302870 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302872 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002873 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002875 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.DeviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302876 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002877 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002878 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.DeviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002879 "Type": pActionSetField.Field.GetOfbField().Type})
2880 }
2881 }
2882 /*
2883 default:
2884 {
2885 //all other entires ignored
2886 }
2887 */
2888 }
2889 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302890}
2891
2892//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002893func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002894 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302895 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2896 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2897 var loAddPcp, loSetPcp uint8
2898 var loIPProto uint32
2899 /* the TechProfileId is part of the flow Metadata - compare also comment within
2900 * OLT-Adapter:openolt_flowmgr.go
2901 * Metadata 8 bytes:
2902 * Most Significant 2 Bytes = Inner VLAN
2903 * Next 2 Bytes = Tech Profile ID(TPID)
2904 * Least Significant 4 Bytes = Port ID
2905 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2906 * subscriber related flows.
2907 */
2908
dbainbri4d3a0dc2020-12-02 00:33:42 +00002909 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302910 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002911 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002912 log.Fields{"device-id": dh.DeviceID})
2913 return fmt.Errorf("flow-add invalid metadata: %s", dh.DeviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302914 }
mpagenko551a4d42020-12-08 18:09:20 +00002915 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002916 loCookie := apFlowItem.GetCookie()
2917 loCookieSlice := []uint64{loCookie}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002919 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302920
dbainbri4d3a0dc2020-12-02 00:33:42 +00002921 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002922 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302923 if loIPProto == 2 {
2924 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2925 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002926 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 log.Fields{"device-id": dh.DeviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302928 return nil
2929 }
mpagenko01e726e2020-10-23 09:45:29 +00002930 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002932
2933 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo,
mpagenkodff5dda2020-08-28 11:52:01 +00002936 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2937 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2938 //TODO!!: Use DeviceId within the error response to rwCore
2939 // likewise also in other error response cases to calling components as requested in [VOL-3458]
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002941 }
2942 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002944 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2945 } else {
2946 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2947 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2948 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302949 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002950 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.DeviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002952 }
mpagenko9a304ea2020-12-16 15:54:01 +00002953
ozgecanetsia82b91a62021-05-21 18:54:49 +03002954 var meter *voltha.OfpMeterConfig
2955 if apFlowMetaData != nil {
2956 meter = apFlowMetaData.Meters[0]
2957 }
mpagenkobc4170a2021-08-17 16:42:10 +00002958 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
2959 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
2960 // when different rules are requested concurrently for the same uni
2961 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
2962 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
2963 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.DeviceID, "tpID": loTpID, "uniID": apUniPort.UniID})
2965 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00002966 //SetUniFlowParams() may block on some rule that is suspended-to-add
2967 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002968 err := dh.UniVlanConfigFsmMap[apUniPort.UniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002969 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenkobc4170a2021-08-17 16:42:10 +00002970 dh.lockVlanConfig.RUnlock()
2971 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00002972 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002973 }
mpagenkobc4170a2021-08-17 16:42:10 +00002974 dh.lockVlanConfig.RUnlock()
2975 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00002976 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 loMatchVlan, loSetVlan, loSetPcp, cmn.OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00002978 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00002979 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko7d14de12021-07-27 08:31:56 +00002980 return err
mpagenko01e726e2020-10-23 09:45:29 +00002981}
2982
2983//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002984func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *cmn.OnuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002985 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2986 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2987 //no extra check is done on the rule parameters
2988 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2989 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2990 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2991 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002992 // - 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 +00002993 loCookie := apFlowItem.GetCookie()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.DeviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002995
2996 /* TT related temporary workaround - should not be needed anymore
2997 for _, field := range flow.GetOfbFields(apFlowItem) {
2998 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2999 loIPProto := field.GetIpProto()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003000 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.DeviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003001 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3002 if loIPProto == 2 {
3003 // 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 +00003004 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003005 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003006 return nil
3007 }
3008 }
3009 } //for all OfbFields
3010 */
3011
mpagenko9a304ea2020-12-16 15:54:01 +00003012 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003013 dh.lockVlanConfig.RLock()
3014 defer dh.lockVlanConfig.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.DeviceID, "uniID": apUniPort.UniID})
3016 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
3017 return dh.UniVlanConfigFsmMap[apUniPort.UniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003018 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003019 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003020 log.Fields{"device-id": dh.DeviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003021 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003022 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003023 go dh.DeviceProcStatusUpdate(ctx, cmn.OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003024
mpagenko01e726e2020-10-23 09:45:29 +00003025 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003026}
3027
Himani Chawla26e555c2020-08-31 12:30:20 +05303028// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003029// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003030// precondition: dh.lockVlanConfig is locked by the caller!
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8, aCookieSlice []uint64,
3032 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent cmn.OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
3033 chVlanFilterFsm := make(chan cmn.Message, 2048)
mpagenkodff5dda2020-08-28 11:52:01 +00003034
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003036 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003037 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.DeviceID})
3038 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003039 }
3040
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003041 pVlanFilterFsm := avcfg.NewUniVlanConfigFsm(ctx, dh, pDevEntry, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
3042 pDevEntry.GetOnuDB(), aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003043 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003044 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003045 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3046 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003047 dh.UniVlanConfigFsmMap[apUniPort.UniID] = pVlanFilterFsm
3048 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003049 if pVlanFilterStatemachine != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 if pVlanFilterStatemachine.Is(avcfg.VlanStDisabled) {
3051 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003052 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003053 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003054 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303055 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003056 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3058 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003059 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003060 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID})
3062 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003063 }
3064 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003065 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 "device-id": dh.DeviceID})
3067 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003068 }
3069 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003070 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003071 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
3072 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.DeviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003073 }
3074 return nil
3075}
3076
mpagenkofc4f56e2020-11-04 17:17:49 +00003077//VerifyVlanConfigRequest checks on existence of a given uniPort
3078// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003079func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003080 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003081 var pCurrentUniPort *cmn.OnuUniPort
mpagenkofc4f56e2020-11-04 17:17:49 +00003082 for _, uniPort := range dh.uniEntityMap {
3083 // only if this port is validated for operState transfer
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003084 if uniPort.UniID == uint8(aUniID) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003085 pCurrentUniPort = uniPort
3086 break //found - end search loop
3087 }
3088 }
3089 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003090 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003091 log.Fields{"device-id": dh.DeviceID, "uni-id": aUniID})
mpagenkofc4f56e2020-11-04 17:17:49 +00003092 return
3093 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 dh.VerifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003095}
3096
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003097//VerifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
3098func (dh *deviceHandler) VerifyUniVlanConfigRequest(ctx context.Context, apUniPort *cmn.OnuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003099 //TODO!! verify and start pending flow configuration
3100 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3101 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003102
3103 dh.lockVlanConfig.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003104 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.UniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003105 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003106 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003107 pVlanFilterStatemachine := pVlanFilterFsm.PAdaptFsm.PFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003108 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003109 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3110 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003111 if pVlanFilterStatemachine.Is(avcfg.VlanStWaitingTechProf) {
3112 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvContinueConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003113 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003115 } else {
3116 /***** UniVlanConfigFsm continued */
3117 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3119 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003120 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003121 } else if pVlanFilterStatemachine.Is(avcfg.VlanStIncrFlowWaitTP) {
3122 if err := pVlanFilterStatemachine.Event(avcfg.VlanEvIncrFlowConfig); err != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003123 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003124 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003125 } else {
3126 /***** UniVlanConfigFsm continued */
3127 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003128 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3129 "UniPort": apUniPort.PortNo})
mpagenko551a4d42020-12-08 18:09:20 +00003130 }
mpagenkodff5dda2020-08-28 11:52:01 +00003131 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003132 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003133 "have": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3134 "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003135 }
3136 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003137 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 +00003138 "state": pVlanFilterStatemachine.Current(), "device-id": dh.DeviceID,
3139 "UniPort": apUniPort.PortNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003140 }
3141 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003142 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003143 "device-id": dh.DeviceID, "UniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003144 }
mpagenkof1fc3862021-02-16 10:09:52 +00003145 } else {
3146 dh.lockVlanConfig.RUnlock()
3147 }
mpagenkodff5dda2020-08-28 11:52:01 +00003148}
3149
3150//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3151// 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 +00003152func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *cmn.OnuUniPort) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003153 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003154 "device-id": dh.DeviceID, "uniPort": apUniPort.PortNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003155 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003156 dh.lockVlanConfig.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 delete(dh.UniVlanConfigFsmMap, apUniPort.UniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003158 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003159}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003160
mpagenkof1fc3862021-02-16 10:09:52 +00003161//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *mib.OnuDeviceEntry) error {
mpagenkof1fc3862021-02-16 10:09:52 +00003163 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3164 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3165 // obviously then parallel processing on the cancel must be avoided
3166 // deadline context to ensure completion of background routines waited for
3167 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3168 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3169 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3170
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 aPDevEntry.ResetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003172 var wg sync.WaitGroup
3173 wg.Add(1) // for the 1 go routine to finish
3174
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003175 go aPDevEntry.UpdateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
mpagenkof1fc3862021-02-16 10:09:52 +00003176 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3177
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 return aPDevEntry.GetKvProcessingErrorIndication()
mpagenkof1fc3862021-02-16 10:09:52 +00003179}
3180
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003181//StorePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003182//available for potential reconcilement
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003183func (dh *deviceHandler) StorePersUniFlowConfig(ctx context.Context, aUniID uint8,
3184 aUniVlanFlowParams *[]cmn.UniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003185
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003186 if dh.IsReconciling() {
3187 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003188 return nil
3189 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003190 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003191
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003192 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003193 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003194 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.DeviceID})
3195 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003196 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 pDevEntry.UpdateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003198
mpagenkof1fc3862021-02-16 10:09:52 +00003199 if aWriteToKvStore {
3200 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3201 }
3202 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003203}
3204
dbainbri4d3a0dc2020-12-02 00:33:42 +00003205func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003206 defer cancel() //ensure termination of context (may be pro forma)
3207 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003208 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003209 "device-id": dh.DeviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003210}
3211
dbainbri4d3a0dc2020-12-02 00:33:42 +00003212func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003213
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003214 dh.SetDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003215 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003216 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo7d3c5582021-08-11 18:09:44 -04003217 if err := dh.updateDeviceReasonInCore(ctx, &ic.DeviceReason{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 DeviceId: dh.DeviceID,
3219 Reason: cmn.DeviceReasonMap[deviceReason],
khenaidoo7d3c5582021-08-11 18:09:44 -04003220 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003221 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003222 log.Fields{"device-id": dh.DeviceID, "error": err}, cmn.DeviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003223 return err
3224 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003225 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", cmn.DeviceReasonMap[deviceReason], dh.DeviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003226 return nil
3227 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003228 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 +00003229 return nil
3230}
3231
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232func (dh *deviceHandler) StorePersistentData(ctx context.Context) error {
3233 pDevEntry := dh.GetOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003234 if pDevEntry == nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.DeviceID})
3236 return fmt.Errorf("no valid OnuDevice: %s", dh.DeviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003237 }
mpagenkof1fc3862021-02-16 10:09:52 +00003238 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003239}
3240
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003241// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003242// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003243func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3244 dh.lockDevice.RLock()
3245 defer dh.lockDevice.RUnlock()
3246 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003247 return uniPort.EntityID, nil
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003248 }
3249 return 0, errors.New("error-fetching-uni-port")
3250}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003251
3252// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003253func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3254 var errorsList []error
3255 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 -08003256
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003257 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3258 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3259 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3260
3261 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3262 // successfully.
3263 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3264 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3265 if len(errorsList) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003266 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 -08003267 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003268 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003269 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.DeviceID, "pmConfig": dh.pmConfigs})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003270 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003271}
3272
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003273func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3274 var err error
3275 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003276 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003277
3278 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003279 if err = dh.pOnuMetricsMgr.UpdateDefaultFrequency(ctx, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003280 errorsList = append(errorsList, err)
3281 }
3282 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003283 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003284
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003285 return errorsList
3286}
3287
3288func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3289 var err error
3290 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003291 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003292 // Check if group metric related config is updated
3293 for _, v := range pmConfigs.Groups {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003294 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3295 m, ok := dh.pOnuMetricsMgr.GroupMetricMap[v.GroupName]
3296 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003297
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003298 if ok && m.Frequency != v.GroupFreq {
3299 if err = dh.pOnuMetricsMgr.UpdateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003300 errorsList = append(errorsList, err)
3301 }
3302 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003303 if ok && m.Enabled != v.Enabled {
3304 if err = dh.pOnuMetricsMgr.UpdateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003305 errorsList = append(errorsList, err)
3306 }
3307 }
3308 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003309 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003310 return errorsList
3311}
3312
3313func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3314 var err error
3315 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003316 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003317 // Check if standalone metric related config is updated
3318 for _, v := range pmConfigs.Metrics {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003319 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock()
3320 m, ok := dh.pOnuMetricsMgr.StandaloneMetricMap[v.Name]
3321 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003322
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003323 if ok && m.Frequency != v.SampleFreq {
3324 if err = dh.pOnuMetricsMgr.UpdateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003325 errorsList = append(errorsList, err)
3326 }
3327 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003328 if ok && m.Enabled != v.Enabled {
3329 if err = dh.pOnuMetricsMgr.UpdateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003330 errorsList = append(errorsList, err)
3331 }
3332 }
3333 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003334 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003335 return errorsList
3336}
3337
3338// nolint: gocyclo
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003339func (dh *deviceHandler) StartCollector(ctx context.Context) {
Girish Gowdrae09a6202021-01-12 18:10:59 -08003340 logger.Debugf(ctx, "startingCollector")
3341
3342 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003343 go dh.pOnuMetricsMgr.ProcessOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303344 // Create Extended Frame PM ME
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003345 go dh.pOnuMetricsMgr.CreateEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003346 // Initialize the next metric collection time.
3347 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3348 // reset like onu rebooted.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003349 dh.pOnuMetricsMgr.InitializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003350 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003351 for {
3352 select {
3353 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003354 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003355 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003356 // Stop the L2 PM FSM
3357 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003358 if dh.pOnuMetricsMgr.PAdaptFsm != nil && dh.pOnuMetricsMgr.PAdaptFsm.PFsm != nil {
3359 if err := dh.pOnuMetricsMgr.PAdaptFsm.PFsm.Event(pmmgr.L2PmEventStop); err != nil {
3360 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.DeviceID, "err": err})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003361 }
3362 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003363 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.DeviceID})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003364 }
3365 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003366 if dh.pOnuMetricsMgr.GetOmciProcessingStatus() {
3367 dh.pOnuMetricsMgr.StopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003368 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003369 if dh.pOnuMetricsMgr.GetTickGenerationStatus() {
3370 dh.pOnuMetricsMgr.StopTicks <- true
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003371 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003372
Girish Gowdrae09a6202021-01-12 18:10:59 -08003373 return
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003374 case <-time.After(time.Duration(pmmgr.FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3375 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then NextGlobalMetricCollectionTime applies
3376 // If the current time is eqaul to or greater than the NextGlobalMetricCollectionTime, collect the group and standalone metrics
3377 if time.Now().Equal(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime) {
3378 go dh.pOnuMetricsMgr.CollectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003379 // Update the next metric collection time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003380 dh.pOnuMetricsMgr.NextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003381 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003382 } else {
3383 if dh.pmConfigs.Grouped { // metrics are managed as a group
3384 // parse through the group and standalone metrics to see it is time to collect their metrics
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003385 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RLock() // Rlock as we are reading GroupMetricMap and StandaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003386
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003387 for n, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3388 // 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 -08003389 // 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 +00003390 if g.Enabled && !g.IsL2PMCounter && (time.Now().Equal(g.NextCollectionInterval) || time.Now().After(g.NextCollectionInterval)) {
3391 go dh.pOnuMetricsMgr.CollectGroupMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003392 }
3393 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003394 for n, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3395 // If the standalone is enabled AND (current time is equal to OR after NextCollectionInterval, collect the metric)
3396 if m.Enabled && (time.Now().Equal(m.NextCollectionInterval) || time.Now().After(m.NextCollectionInterval)) {
3397 go dh.pOnuMetricsMgr.CollectStandaloneMetric(ctx, n)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003398 }
3399 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003400 dh.pOnuMetricsMgr.OnuMetricsManagerLock.RUnlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003401
3402 // parse through the group and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003403 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3404 for _, g := range dh.pOnuMetricsMgr.GroupMetricMap {
3405 // 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 -08003406 // 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 +00003407 if g.Enabled && !g.IsL2PMCounter && (g.NextCollectionInterval.Before(time.Now()) || g.NextCollectionInterval.Equal(time.Now())) {
3408 g.NextCollectionInterval = time.Now().Add(time.Duration(g.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003409 }
3410 }
3411 // parse through the standalone metrics and update the next metric collection time
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003412 for _, m := range dh.pOnuMetricsMgr.StandaloneMetricMap {
3413 // If standalone metrics enabled, and the NextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3414 if m.Enabled && (m.NextCollectionInterval.Before(time.Now()) || m.NextCollectionInterval.Equal(time.Now())) {
3415 m.NextCollectionInterval = time.Now().Add(time.Duration(m.Frequency) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003416 }
3417 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003418 dh.pOnuMetricsMgr.OnuMetricsManagerLock.Unlock()
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003419 } /* else { // metrics are not managed as a group
3420 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3421 } */
3422 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003423 }
3424 }
3425}
kesavandfdf77632021-01-26 23:40:33 -05003426
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003427func (dh *deviceHandler) GetUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
kesavandfdf77632021-01-26 23:40:33 -05003428
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003429 portStatus := uniprt.NewUniPortStatus(dh, dh.pOnuOmciDevice.PDevOmciCC)
3430 return portStatus.GetUniPortStatus(ctx, uniInfo.UniIndex)
kesavandfdf77632021-01-26 23:40:33 -05003431}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003432
Himani Chawla43f95ff2021-06-03 00:24:12 +05303433func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3434 if dh.pOnuMetricsMgr == nil {
3435 return &extension.SingleGetValueResponse{
3436 Response: &extension.GetValueResponse{
3437 Status: extension.GetValueResponse_ERROR,
3438 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3439 },
3440 }
3441 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003442 resp := dh.pOnuMetricsMgr.CollectEthernetFrameExtendedPMCounters(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303443 return resp
3444}
3445
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003446func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, PFsm *fsm.FSM, wantedState string) bool {
3447 if PFsm == nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003448 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003449 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003450 return PFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003451}
3452
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003453func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, wantedState string) bool {
3454 var PFsm *fsm.FSM
mpagenkof1fc3862021-02-16 10:09:52 +00003455 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3456 switch omciFsm {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003457 case cmn.CUploadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003458 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003459 PFsm = dh.pOnuOmciDevice.PMibUploadFsm.PFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003460 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003461 case cmn.CDownloadFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003462 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003463 PFsm = dh.pOnuOmciDevice.PMibDownloadFsm.PFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003464 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003465 case cmn.CUniLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003466 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003467 PFsm = dh.pLockStateFsm.PAdaptFsm.PFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003468 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003469 case cmn.CUniUnLockFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003470 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003471 PFsm = dh.pUnlockStateFsm.PAdaptFsm.PFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003472 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003473 case cmn.CL2PmFsm:
mpagenkof1fc3862021-02-16 10:09:52 +00003474 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003475 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.PAdaptFsm != nil {
3476 PFsm = dh.pOnuMetricsMgr.PAdaptFsm.PFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003477 } else {
3478 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003479 }
3480 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003481 case cmn.COnuUpgradeFsm:
mpagenko80622a52021-02-09 16:53:23 +00003482 {
3483 dh.lockUpgradeFsm.RLock()
3484 defer dh.lockUpgradeFsm.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003485 PFsm = dh.pOnuUpradeFsm.PAdaptFsm.PFsm
mpagenko80622a52021-02-09 16:53:23 +00003486 }
mpagenkof1fc3862021-02-16 10:09:52 +00003487 default:
3488 {
3489 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003490 "device-id": dh.DeviceID, "selectedFsm number": omciFsm})
mpagenkof1fc3862021-02-16 10:09:52 +00003491 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003492 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003493 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003494 return dh.isFsmInOmciIdleState(ctx, PFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003495}
3496
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003497func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
3498 for _, v := range dh.pOnuTP.PAniConfigFsm {
3499 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003500 return false
3501 }
3502 }
3503 return true
3504}
3505
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003506func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm cmn.UsedOmciConfigFsms, idleState string) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003507 dh.lockVlanConfig.RLock()
3508 defer dh.lockVlanConfig.RUnlock()
3509 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003510 if !dh.isFsmInOmciIdleState(ctx, v.PAdaptFsm.PFsm, idleState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003511 return false
3512 }
3513 }
3514 return true //FSM not active - so there is no activity on omci
3515}
3516
3517func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3518 dh.lockVlanConfig.RLock()
3519 defer dh.lockVlanConfig.RUnlock()
3520 for _, v := range dh.UniVlanConfigFsmMap {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003521 if v.PAdaptFsm.PFsm != nil {
3522 if v.PAdaptFsm.PFsm.Is(avcfg.CVlanFsmConfiguredState) {
mpagenkof1fc3862021-02-16 10:09:52 +00003523 return true //there is at least one VLAN FSM with some active configuration
3524 }
3525 }
3526 }
3527 return false //there is no VLAN FSM with some active configuration
3528}
3529
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003530func (dh *deviceHandler) CheckAuditStartCondition(ctx context.Context, callingFsm cmn.UsedOmciConfigFsms) bool {
mpagenkof1fc3862021-02-16 10:09:52 +00003531 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3532 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3533 return false
3534 }
3535 }
3536 // a further check is done to identify, if at least some data traffic related configuration exists
3537 // 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])
3538 return dh.checkUserServiceExists(ctx)
3539}
3540
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003541func (dh *deviceHandler) PrepareReconcilingWithActiveAdapter(ctx context.Context) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003542 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3543 if err := dh.resetFsms(ctx, false); err != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003544 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.DeviceID, "error": err})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003545 // TODO: fatal error reset ONU, delete deviceHandler!
3546 return
3547 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003548 dh.uniEntityMap = make(map[uint32]*cmn.OnuUniPort)
3549 dh.StartReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003550}
3551
3552func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3553 dh.mutexCollectorFlag.Lock()
3554 dh.collectorIsRunning = flagValue
3555 dh.mutexCollectorFlag.Unlock()
3556}
3557
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003558func (dh *deviceHandler) GetCollectorIsRunning() bool {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003559 dh.mutexCollectorFlag.RLock()
3560 flagValue := dh.collectorIsRunning
3561 dh.mutexCollectorFlag.RUnlock()
3562 return flagValue
3563}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303564
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303565func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3566 dh.mutextAlarmManagerFlag.Lock()
3567 dh.alarmManagerIsRunning = flagValue
3568 dh.mutextAlarmManagerFlag.Unlock()
3569}
3570
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003571func (dh *deviceHandler) GetAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303572 dh.mutextAlarmManagerFlag.RLock()
3573 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303574 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303575 dh.mutextAlarmManagerFlag.RUnlock()
3576 return flagValue
3577}
3578
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003579func (dh *deviceHandler) StartAlarmManager(ctx context.Context) {
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303580 logger.Debugf(ctx, "startingAlarmManager")
3581
3582 // Start routine to process OMCI GET Responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003583 go dh.pAlarmMgr.StartOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303584 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303585 if stop := <-dh.stopAlarmManager; stop {
3586 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303587 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303588 go func() {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003589 if dh.pAlarmMgr.AlarmSyncFsm != nil && dh.pAlarmMgr.AlarmSyncFsm.PFsm != nil {
3590 _ = dh.pAlarmMgr.AlarmSyncFsm.PFsm.Event(almgr.AsEvStop)
Himani Chawla1472c682021-03-17 17:11:14 +05303591 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303592 }()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003593 dh.pAlarmMgr.StopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
3594 dh.pAlarmMgr.StopAlarmAuditTimer <- struct{}{}
Himani Chawla1472c682021-03-17 17:11:14 +05303595 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303596 }
3597}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003598
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003599func (dh *deviceHandler) StartReconciling(ctx context.Context, skipOnuConfig bool) {
3600 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.DeviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003601
Maninder7961d722021-06-16 22:10:28 +05303602 connectStatus := voltha.ConnectStatus_UNREACHABLE
3603 operState := voltha.OperStatus_UNKNOWN
3604
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003605 if !dh.IsReconciling() {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003606 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003607 logger.Debugw(ctx, "wait for channel signal or timeout",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003608 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003609 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003610 case success := <-dh.chReconcilingFinished:
3611 if success {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003612 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninderb5187552021-03-23 22:23:42 +05303613 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003614 log.Fields{"device-id": dh.DeviceID})
Maninderb5187552021-03-23 22:23:42 +05303615 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003616 if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninderb5187552021-03-23 22:23:42 +05303617 connectStatus = voltha.ConnectStatus_REACHABLE
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003618 if !onuDevEntry.SOnuPersistentData.PersUniDisableDone {
3619 if onuDevEntry.SOnuPersistentData.PersUniUnlockDone {
Maninderb5187552021-03-23 22:23:42 +05303620 operState = voltha.OperStatus_ACTIVE
3621 } else {
3622 operState = voltha.OperStatus_ACTIVATING
3623 }
3624 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003625 } else if onuDevEntry.SOnuPersistentData.PersOperState == "down" ||
3626 onuDevEntry.SOnuPersistentData.PersOperState == "unknown" ||
3627 onuDevEntry.SOnuPersistentData.PersOperState == "" {
Maninderb5187552021-03-23 22:23:42 +05303628 operState = voltha.OperStatus_DISCOVERED
3629 }
3630
3631 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303632 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003633 logger.Debugw(ctx, "reconciling has been finished in time",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003634 log.Fields{"device-id": dh.DeviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04003635 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003636 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003637 ConnStatus: connectStatus,
3638 OperStatus: operState,
3639 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303640 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003641 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303642 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003643 } else {
Maninderb5187552021-03-23 22:23:42 +05303644 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003645 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303646
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003647 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303648 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003649 log.Fields{"device-id": dh.DeviceID})
3650 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303651 connectStatus = voltha.ConnectStatus_REACHABLE
3652 }
3653
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003654 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003655 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003656 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003657 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003658 log.Fields{"device-id": dh.DeviceID})
Maninder7961d722021-06-16 22:10:28 +05303659
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003660 if onuDevEntry := dh.GetOnuDeviceEntry(ctx, true); onuDevEntry == nil {
Maninder7961d722021-06-16 22:10:28 +05303661 logger.Errorw(ctx, "No valid OnuDevice",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003662 log.Fields{"device-id": dh.DeviceID})
3663 } else if onuDevEntry.SOnuPersistentData.PersOperState == "up" {
Maninder7961d722021-06-16 22:10:28 +05303664 connectStatus = voltha.ConnectStatus_REACHABLE
3665 }
3666
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003667 dh.deviceReconcileFailedUpdate(ctx, cmn.DrReconcileMaxTimeout, connectStatus)
Maninder7961d722021-06-16 22:10:28 +05303668
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003669 }
3670 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003671 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003672 dh.mutexReconcilingFlag.Unlock()
3673 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003674 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003675 dh.mutexReconcilingFlag.Lock()
3676 if skipOnuConfig {
3677 dh.reconciling = cSkipOnuConfigReconciling
3678 } else {
3679 dh.reconciling = cOnuConfigReconciling
3680 }
3681 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003682}
3683
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003684func (dh *deviceHandler) StopReconciling(ctx context.Context, success bool) {
3685 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.DeviceID, "success": success})
3686 if dh.IsReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003687 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003688 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003689 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.DeviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003690 }
3691}
3692
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003693func (dh *deviceHandler) IsReconciling() bool {
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003694 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003695 defer dh.mutexReconcilingFlag.RUnlock()
3696 return dh.reconciling != cNoReconciling
3697}
3698
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003699func (dh *deviceHandler) IsSkipOnuConfigReconciling() bool {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003700 dh.mutexReconcilingFlag.RLock()
3701 defer dh.mutexReconcilingFlag.RUnlock()
3702 return dh.reconciling == cSkipOnuConfigReconciling
3703}
3704
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003705func (dh *deviceHandler) SetDeviceReason(value uint8) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003706 dh.mutexDeviceReason.Lock()
3707 dh.deviceReason = value
3708 dh.mutexDeviceReason.Unlock()
3709}
3710
3711func (dh *deviceHandler) getDeviceReason() uint8 {
3712 dh.mutexDeviceReason.RLock()
3713 value := dh.deviceReason
3714 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003715 return value
3716}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003717
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003718func (dh *deviceHandler) GetDeviceReasonString() string {
3719 return cmn.DeviceReasonMap[dh.getDeviceReason()]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003720}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003721
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003722func (dh *deviceHandler) SetReadyForOmciConfig(flagValue bool) {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003723 dh.mutexReadyForOmciConfig.Lock()
3724 dh.readyForOmciConfig = flagValue
3725 dh.mutexReadyForOmciConfig.Unlock()
3726}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003727func (dh *deviceHandler) IsReadyForOmciConfig() bool {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003728 dh.mutexReadyForOmciConfig.RLock()
3729 flagValue := dh.readyForOmciConfig
3730 dh.mutexReadyForOmciConfig.RUnlock()
3731 return flagValue
3732}
Maninder7961d722021-06-16 22:10:28 +05303733
3734func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3735 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3736 logger.Errorw(ctx, "unable to update device reason to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003737 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303738 }
3739
3740 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo7d3c5582021-08-11 18:09:44 -04003741 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003742 DeviceId: dh.DeviceID,
khenaidoo7d3c5582021-08-11 18:09:44 -04003743 ConnStatus: connectStatus,
3744 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3745 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303746 logger.Errorw(ctx, "unable to update device state to core",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003747 log.Fields{"device-id": dh.DeviceID, "Err": err})
Maninder7961d722021-06-16 22:10:28 +05303748 }
3749}
khenaidoo7d3c5582021-08-11 18:09:44 -04003750
3751/*
3752Helper functions to communicate with Core
3753*/
3754
3755func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3756 cClient, err := dh.coreClient.GetCoreServiceClient()
3757 if err != nil || cClient == nil {
3758 return nil, err
3759 }
3760 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3761 defer cancel()
3762 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3763 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3764}
3765
3766func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
3767 cClient, err := dh.coreClient.GetCoreServiceClient()
3768 if err != nil || cClient == nil {
3769 return err
3770 }
3771 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3772 defer cancel()
3773 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3774 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3775 return err
3776}
3777
3778func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3779 cClient, err := dh.coreClient.GetCoreServiceClient()
3780 if err != nil || cClient == nil {
3781 return err
3782 }
3783 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3784 defer cancel()
3785 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
3786 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
3787 return err
3788}
3789
3790func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
3791 cClient, err := dh.coreClient.GetCoreServiceClient()
3792 if err != nil || cClient == nil {
3793 return err
3794 }
3795 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3796 defer cancel()
3797 _, err = cClient.DeviceUpdate(subCtx, device)
3798 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
3799 return err
3800}
3801
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003802func (dh *deviceHandler) CreatePortInCore(ctx context.Context, port *voltha.Port) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04003803 cClient, err := dh.coreClient.GetCoreServiceClient()
3804 if err != nil || cClient == nil {
3805 return err
3806 }
3807 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3808 defer cancel()
3809 _, err = cClient.PortCreated(subCtx, port)
3810 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
3811 return err
3812}
3813
3814func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
3815 cClient, err := dh.coreClient.GetCoreServiceClient()
3816 if err != nil || cClient == nil {
3817 return err
3818 }
3819 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3820 defer cancel()
3821 _, err = cClient.PortStateUpdate(subCtx, portState)
3822 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
3823 return err
3824}
3825
3826func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ic.DeviceReason) error {
3827 cClient, err := dh.coreClient.GetCoreServiceClient()
3828 if err != nil || cClient == nil {
3829 return err
3830 }
3831 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3832 defer cancel()
3833 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
3834 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
3835 return err
3836}
3837
3838/*
3839Helper functions to communicate with parent adapter
3840*/
3841
3842func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
3843 request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
3844 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
3845 if err != nil || pgClient == nil {
3846 return nil, err
3847 }
3848 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
3849 defer cancel()
3850 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
3851 return pgClient.GetTechProfileInstance(subCtx, request)
3852}
3853
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003854func (dh *deviceHandler) SendOMCIRequest(ctx context.Context, parentEndpoint string, request *ic.OmciMessage) error {
khenaidoo7d3c5582021-08-11 18:09:44 -04003855 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
3856 if err != nil || pgClient == nil {
3857 return err
3858 }
3859 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
3860 defer cancel()
3861 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
3862 _, err = pgClient.ProxyOmciRequest(subCtx, request)
3863 if err != nil {
3864 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
3865 }
3866 return err
3867}
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003868
3869// GetDeviceID - TODO: add comment
3870func (dh *deviceHandler) GetDeviceID() string {
3871 return dh.DeviceID
3872}
3873
3874// GetProxyAddressID - TODO: add comment
3875func (dh *deviceHandler) GetProxyAddressID() string {
3876 return dh.device.ProxyAddress.GetDeviceId()
3877}
3878
3879// GetProxyAddressType - TODO: add comment
3880func (dh *deviceHandler) GetProxyAddressType() string {
3881 return dh.device.ProxyAddress.GetDeviceType()
3882}
3883
3884// GetProxyAddress - TODO: add comment
3885func (dh *deviceHandler) GetProxyAddress() *voltha.Device_ProxyAddress {
3886 return dh.device.ProxyAddress
3887}
3888
3889// GetEventProxy - TODO: add comment
3890func (dh *deviceHandler) GetEventProxy() eventif.EventProxy {
3891 return dh.EventProxy
3892}
3893
3894// GetOmciTimeout - TODO: add comment
3895func (dh *deviceHandler) GetOmciTimeout() int {
3896 return dh.pOpenOnuAc.omciTimeout
3897}
3898
3899// GetAlarmAuditInterval - TODO: add comment
3900func (dh *deviceHandler) GetAlarmAuditInterval() time.Duration {
3901 return dh.pOpenOnuAc.alarmAuditInterval
3902}
3903
3904// GetDlToOnuTimeout4M - TODO: add comment
3905func (dh *deviceHandler) GetDlToOnuTimeout4M() time.Duration {
3906 return dh.pOpenOnuAc.dlToOnuTimeout4M
3907}
3908
3909// GetUniEntityMap - TODO: add comment
3910func (dh *deviceHandler) GetUniEntityMap() *cmn.OnuUniPortMap {
3911 return &dh.uniEntityMap
3912}
3913
3914// GetPonPortNumber - TODO: add comment
3915func (dh *deviceHandler) GetPonPortNumber() *uint32 {
3916 return &dh.ponPortNumber
3917}
3918
3919// GetUniVlanConfigFsm - TODO: add comment
3920func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) cmn.IuniVlanConfigFsm {
3921 return dh.UniVlanConfigFsmMap[uniID]
3922}
3923
3924// GetOnuAlarmManager - TODO: add comment
3925func (dh *deviceHandler) GetOnuAlarmManager() cmn.IonuAlarmManager {
3926 return dh.pAlarmMgr
3927}
3928
3929// GetOnuMetricsManager - TODO: add comment
3930func (dh *deviceHandler) GetOnuMetricsManager() cmn.IonuMetricsManager {
3931 return dh.pOnuMetricsMgr
3932}
3933
3934// GetOnuTP - TODO: add comment
3935func (dh *deviceHandler) GetOnuTP() cmn.IonuUniTechProf {
3936 return dh.pOnuTP
3937}
3938
3939// GetBackendPathPrefix - TODO: add comment
3940func (dh *deviceHandler) GetBackendPathPrefix() string {
3941 return dh.pOpenOnuAc.cm.Backend.PathPrefix
3942}
3943
3944// GetOnuIndication - TODO: add comment
3945func (dh *deviceHandler) GetOnuIndication() *openolt.OnuIndication {
3946 return dh.pOnuIndication
3947}
3948
3949// RLockMutexDeletionInProgressFlag - TODO: add comment
3950func (dh *deviceHandler) RLockMutexDeletionInProgressFlag() {
3951 dh.mutexDeletionInProgressFlag.RLock()
3952}
3953
3954// RUnlockMutexDeletionInProgressFlag - TODO: add comment
3955func (dh *deviceHandler) RUnlockMutexDeletionInProgressFlag() {
3956 dh.mutexDeletionInProgressFlag.RUnlock()
3957}
3958
3959// GetDeletionInProgress - TODO: add comment
3960func (dh *deviceHandler) GetDeletionInProgress() bool {
3961 return dh.deletionInProgress
3962}
3963
3964// GetPmConfigs - TODO: add comment
3965func (dh *deviceHandler) GetPmConfigs() *voltha.PmConfigs {
3966 return dh.pmConfigs
3967}
3968
3969// GetDeviceType - TODO: add comment
3970func (dh *deviceHandler) GetDeviceType() string {
3971 return dh.DeviceType
3972}
3973
3974// GetLogicalDeviceID - TODO: add comment
3975func (dh *deviceHandler) GetLogicalDeviceID() string {
3976 return dh.logicalDeviceID
3977}
3978
3979// GetDevice - TODO: add comment
3980func (dh *deviceHandler) GetDevice() *voltha.Device {
3981 return dh.device
3982}
3983
3984// GetMetricsEnabled - TODO: add comment
3985func (dh *deviceHandler) GetMetricsEnabled() bool {
3986 return dh.pOpenOnuAc.MetricsEnabled
3987}
3988
3989// InitPmConfigs - TODO: add comment
3990func (dh *deviceHandler) InitPmConfigs() {
3991 dh.pmConfigs = &voltha.PmConfigs{}
3992}
3993
3994// GetUniPortMask - TODO: add comment
3995func (dh *deviceHandler) GetUniPortMask() int {
3996 return dh.pOpenOnuAc.config.UniPortMask
3997}