blob: 2c5a4c8543171610bf6d11648ecd84de226d5345 [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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
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"
29 "github.com/opencord/voltha-protos/v5/go/tech_profile"
mpagenko1f8e8822021-06-25 14:10:21 +000030
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000031 "github.com/gogo/protobuf/proto"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000032 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000033 me "github.com/opencord/omci-lib-go/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040034 "github.com/opencord/voltha-lib-go/v7/pkg/db"
35 "github.com/opencord/voltha-lib-go/v7/pkg/events/eventif"
36 flow "github.com/opencord/voltha-lib-go/v7/pkg/flows"
37 vgrpc "github.com/opencord/voltha-lib-go/v7/pkg/grpc"
38 "github.com/opencord/voltha-lib-go/v7/pkg/log"
39 vc "github.com/opencord/voltha-protos/v5/go/common"
40 "github.com/opencord/voltha-protos/v5/go/extension"
41 ic "github.com/opencord/voltha-protos/v5/go/inter_container"
42 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v5/go/openolt"
44 "github.com/opencord/voltha-protos/v5/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
mpagenko38662d02021-08-11 09:45:19 +000047// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000048const (
mpagenko38662d02021-08-11 09:45:19 +000049 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000050)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000051
mpagenko1cc3cb42020-07-27 15:24:38 +000052const (
53 // events of Device FSM
54 devEvDeviceInit = "devEvDeviceInit"
55 devEvGrpcConnected = "devEvGrpcConnected"
56 devEvGrpcDisconnected = "devEvGrpcDisconnected"
57 devEvDeviceUpInd = "devEvDeviceUpInd"
58 devEvDeviceDownInd = "devEvDeviceDownInd"
59)
60const (
61 // states of Device FSM
62 devStNull = "devStNull"
63 devStDown = "devStDown"
64 devStInit = "devStInit"
65 devStConnected = "devStConnected"
66 devStUp = "devStUp"
67)
68
Holger Hildebrandt24d51952020-05-04 14:03:42 +000069//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
70const (
Himani Chawla4d908332020-08-31 12:30:20 +053071 pon = voltha.EventSubCategory_PON
72 //olt = voltha.EventSubCategory_OLT
73 //ont = voltha.EventSubCategory_ONT
74 //onu = voltha.EventSubCategory_ONU
75 //nni = voltha.EventSubCategory_NNI
76 //service = voltha.EventCategory_SERVICE
77 //security = voltha.EventCategory_SECURITY
78 equipment = voltha.EventCategory_EQUIPMENT
79 //processing = voltha.EventCategory_PROCESSING
80 //environment = voltha.EventCategory_ENVIRONMENT
81 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000082)
83
84const (
85 cEventObjectType = "ONU"
86)
87const (
88 cOnuActivatedEvent = "ONU_ACTIVATED"
89)
90
Holger Hildebrandt10d98192021-01-27 15:29:31 +000091type usedOmciConfigFsms int
92
93const (
94 cUploadFsm usedOmciConfigFsms = iota
95 cDownloadFsm
96 cUniLockFsm
97 cUniUnLockFsm
98 cAniConfigFsm
99 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800100 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000101 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000102)
103
mpagenkof1fc3862021-02-16 10:09:52 +0000104type omciIdleCheckStruct struct {
105 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
106 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000107}
108
mpagenkof1fc3862021-02-16 10:09:52 +0000109var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
110 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
111 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
112 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
113 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
114 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
115 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
116 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000117 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000118}
119
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000120const (
121 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000122 drUnset = 0
123 drActivatingOnu = 1
124 drStartingOpenomci = 2
125 drDiscoveryMibsyncComplete = 3
126 drInitialMibDownloaded = 4
127 drTechProfileConfigDownloadSuccess = 5
128 drOmciFlowsPushed = 6
129 drOmciAdminLock = 7
130 drOnuReenabled = 8
131 drStoppingOpenomci = 9
132 drRebooting = 10
133 drOmciFlowsDeleted = 11
134 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530135 drReconcileFailed = 13
136 drReconcileMaxTimeout = 14
137 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700138 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000139)
140
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000141var deviceReasonMap = map[uint8]string{
142 drUnset: "unset",
143 drActivatingOnu: "activating-onu",
144 drStartingOpenomci: "starting-openomci",
145 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
146 drInitialMibDownloaded: "initial-mib-downloaded",
147 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700148 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000149 drOmciFlowsPushed: "omci-flows-pushed",
150 drOmciAdminLock: "omci-admin-lock",
151 drOnuReenabled: "onu-reenabled",
152 drStoppingOpenomci: "stopping-openomci",
153 drRebooting: "rebooting",
154 drOmciFlowsDeleted: "omci-flows-deleted",
155 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530156 drReconcileFailed: "reconcile-failed",
157 drReconcileMaxTimeout: "reconcile-max-timeout",
158 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000159}
160
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000161const (
162 cNoReconciling = iota
163 cOnuConfigReconciling
164 cSkipOnuConfigReconciling
165)
166
Himani Chawla6d2ae152020-09-02 13:11:20 +0530167//deviceHandler will interact with the ONU ? device.
168type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000169 deviceID string
170 DeviceType string
171 adminState string
172 device *voltha.Device
173 logicalDeviceID string
174 ProxyAddressID string
175 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530176 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000177 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178
khenaidoo7d3c5582021-08-11 18:09:44 -0400179 coreClient *vgrpc.Client
180 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000181
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800182 pmConfigs *voltha.PmConfigs
khenaidoo7d3c5582021-08-11 18:09:44 -0400183 config *config.AdapterFlags
Girish Gowdrae09a6202021-01-12 18:10:59 -0800184
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000185 pOpenOnuAc *OpenONUAC
186 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530187 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000188 deviceEntrySet chan bool //channel for DeviceEntry set event
189 pOnuOmciDevice *OnuDeviceEntry
190 pOnuTP *onuUniTechProf
191 pOnuMetricsMgr *onuMetricsManager
192 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700193 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000194 exitChannel chan int
195 lockDevice sync.RWMutex
196 pOnuIndication *oop.OnuIndication
197 deviceReason uint8
198 mutexDeviceReason sync.RWMutex
199 pLockStateFsm *lockStateFsm
200 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000201
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000202 //flowMgr *OpenOltFlowMgr
203 //eventMgr *OpenOltEventMgr
204 //resourceMgr *rsrcMgr.OpenOltResourceMgr
205
206 //discOnus sync.Map
207 //onus sync.Map
208 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000209 collectorIsRunning bool
210 mutexCollectorFlag sync.RWMutex
211 stopCollector chan bool
212 alarmManagerIsRunning bool
213 mutextAlarmManagerFlag sync.RWMutex
214 stopAlarmManager chan bool
215 stopHeartbeatCheck chan bool
216 uniEntityMap map[uint32]*onuUniPort
217 mutexKvStoreContext sync.Mutex
218 lockVlanConfig sync.RWMutex
mpagenkobc4170a2021-08-17 16:42:10 +0000219 lockVlanAdd sync.RWMutex
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000220 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
221 lockUpgradeFsm sync.RWMutex
222 pOnuUpradeFsm *OnuUpgradeFsm
223 reconciling uint8
224 mutexReconcilingFlag sync.RWMutex
225 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000226 reconcilingFlows bool
227 mutexReconcilingFlowsFlag sync.RWMutex
228 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000229 mutexReadyForOmciConfig sync.RWMutex
230 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000231 deletionInProgress bool
232 mutexDeletionInProgressFlag sync.RWMutex
mpagenko38662d02021-08-11 09:45:19 +0000233 pLastUpgradeImageState *voltha.ImageState
234 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235}
236
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237//newDeviceHandler creates a new device handler
khenaidoo7d3c5582021-08-11 18:09:44 -0400238func newDeviceHandler(ctx context.Context, cc *vgrpc.Client, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239 var dh deviceHandler
khenaidoo7d3c5582021-08-11 18:09:44 -0400240 dh.coreClient = cc
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000241 dh.EventProxy = ep
khenaidoo7d3c5582021-08-11 18:09:44 -0400242 dh.config = adapter.config
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 cloned := (proto.Clone(device)).(*voltha.Device)
244 dh.deviceID = cloned.Id
245 dh.DeviceType = cloned.Type
246 dh.adminState = "up"
247 dh.device = cloned
248 dh.pOpenOnuAc = adapter
249 dh.exitChannel = make(chan int, 1)
250 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000251 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000252 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000253 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530254 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530255 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopHeartbeatCheck = make(chan bool, 2)
257 //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 +0000258 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530259 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000260 dh.lockVlanConfig = sync.RWMutex{}
mpagenkobc4170a2021-08-17 16:42:10 +0000261 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000262 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000263 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000264 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000265 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000266 dh.reconcilingFlows = false
267 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000268 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000269 dh.deletionInProgress = false
mpagenko38662d02021-08-11 09:45:19 +0000270 dh.pLastUpgradeImageState = &voltha.ImageState{
271 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
272 Reason: voltha.ImageState_UNKNOWN_ERROR,
273 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
274 }
275 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800277 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
278 dh.pmConfigs = cloned.PmConfigs
279 } /* else {
280 // will be populated when onu_metrics_mananger is initialized.
281 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800282
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000283 // Device related state machine
284 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000285 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000287 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
288 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
289 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
290 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
291 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000292 },
293 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
295 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
296 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
297 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
298 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
299 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
300 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
301 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 },
303 )
mpagenkoaf801632020-07-03 10:00:42 +0000304
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 return &dh
306}
307
Himani Chawla6d2ae152020-09-02 13:11:20 +0530308// start save the device to the data model
309func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000310 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313}
314
Himani Chawla4d908332020-08-31 12:30:20 +0530315/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530317func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 logger.Debug("stopping-device-handler")
319 dh.exitChannel <- 1
320}
Himani Chawla4d908332020-08-31 12:30:20 +0530321*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000322
323// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530324// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
Girish Gowdrae0140f02021-02-02 16:55:09 -0800326//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400328 logger.Debugw(ctx, "adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000331 if dh.pDeviceStateFsm.Is(devStNull) {
332 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000334 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000335 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800336 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
337 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800338 // Now, set the initial PM configuration for that device
khenaidoo7d3c5582021-08-11 18:09:44 -0400339 if err := dh.updatePMConfigInCore(ctx, dh.pmConfigs); err != nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800340 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
341 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800342 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000343 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000345 }
346
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000347}
348
khenaidoo7d3c5582021-08-11 18:09:44 -0400349func (dh *deviceHandler) handleOMCIIndication(ctx context.Context, msg *ic.OmciMessage) error {
mpagenko80622a52021-02-09 16:53:23 +0000350 /* 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 +0530351 //assuming omci message content is hex coded!
352 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530354 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000355 */
khenaidoo7d3c5582021-08-11 18:09:44 -0400356
dbainbri4d3a0dc2020-12-02 00:33:42 +0000357 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530358 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000359 if pDevEntry.PDevOmciCC != nil {
khenaidoo7d3c5582021-08-11 18:09:44 -0400360 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), msg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000361 }
khenaidoo7d3c5582021-08-11 18:09:44 -0400362 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 +0530363 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000365 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530366}
367
khenaidoo7d3c5582021-08-11 18:09:44 -0400368func (dh *deviceHandler) handleTechProfileDownloadRequest(ctx context.Context, techProfMsg *ic.TechProfileDownloadMessage) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000369 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000370
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000372 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
375 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 if dh.pOnuTP == nil {
377 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530379 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000380 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000382 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000384 "device-state": dh.getDeviceReasonString()})
385 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000387 //previous state test here was just this one, now extended for more states to reject the SetRequest:
388 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
389 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530390
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000392 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
393 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000396
397 if techProfMsg.UniId > 255 {
398 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
399 techProfMsg.UniId, dh.deviceID))
400 }
401 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700402 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800403 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700404 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800405 return err
406 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700407 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408
Girish Gowdra50e56422021-06-01 16:46:04 -0700409 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530410
Girish Gowdra50e56422021-06-01 16:46:04 -0700411 switch tpInst := techProfMsg.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400412 case *ic.TechProfileDownloadMessage_TpInstance:
Girish Gowdra50e56422021-06-01 16:46:04 -0700413 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
414 // if there has been some change for some uni TechProfilePath
415 //in order to allow concurrent calls to other dh instances we do not wait for execution here
416 //but doing so we can not indicate problems to the caller (who does what with that then?)
417 //by now we just assume straightforward successful execution
418 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
419 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530420
Girish Gowdra50e56422021-06-01 16:46:04 -0700421 // deadline context to ensure completion of background routines waited for
422 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
423 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
424 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425
Girish Gowdra50e56422021-06-01 16:46:04 -0700426 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
427
428 var wg sync.WaitGroup
429 wg.Add(1) // for the 1 go routine to finish
430 // attention: deadline completion check and wg.Done is to be done in both routines
431 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
432 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
433 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
434 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
435 return tpErr
436 }
437 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
438 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
439 pDevEntry.resetKvProcessingErrorIndication()
440 wg.Add(1) // for the 1 go routine to finish
441 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
442 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
443 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
444 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
445 return kvErr
446 }
447 return nil
448 default:
449 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
450 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700451 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530452 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000453 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700454 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 +0530455 return nil
456}
457
khenaidoo7d3c5582021-08-11 18:09:44 -0400458func (dh *deviceHandler) handleDeleteGemPortRequest(ctx context.Context, delGemPortMsg *ic.DeleteGemPortMessage) error {
459 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530460
461 if dh.pOnuTP == nil {
462 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000463 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530464 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000465 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530466 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530467 //compare TECH_PROFILE_DOWNLOAD_REQUEST
468 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530470
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000471 if delGemPortMsg.UniId > 255 {
472 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
473 delGemPortMsg.UniId, dh.deviceID))
474 }
475 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700476 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800477 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700478 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 -0800479 return err
480 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700481 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 +0000482 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000483
Mahir Gunyel9545be22021-07-04 15:53:16 -0700484 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
485 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486
Himani Chawla26e555c2020-08-31 12:30:20 +0530487}
488
khenaidoo7d3c5582021-08-11 18:09:44 -0400489func (dh *deviceHandler) handleDeleteTcontRequest(ctx context.Context, delTcontMsg *ic.DeleteTcontMessage) error {
490 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000491
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000493 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000494 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000495 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
496 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530497 if dh.pOnuTP == nil {
498 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530502 }
503
Himani Chawla26e555c2020-08-31 12:30:20 +0530504 //compare TECH_PROFILE_DOWNLOAD_REQUEST
505 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507
508 if delTcontMsg.UniId > 255 {
509 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
510 delTcontMsg.UniId, dh.deviceID))
511 }
512 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700513 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800514 tpID, err := GetTpIDFromTpPath(tpPath)
515 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000516 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800517 return err
518 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700519 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 +0000520
Mahir Gunyel9545be22021-07-04 15:53:16 -0700521 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530522
Mahir Gunyel9545be22021-07-04 15:53:16 -0700523 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
524 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525
Mahir Gunyel9545be22021-07-04 15:53:16 -0700526}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
Mahir Gunyel9545be22021-07-04 15:53:16 -0700528func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
529 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
530 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
531 if pDevEntry == nil {
532 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
533 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 }
Mahir Gunyel9545be22021-07-04 15:53:16 -0700535 var resourceName string
536 if cResourceGemPort == resource {
537 resourceName = "Gem"
538 } else {
539 resourceName = "Tcont"
540 }
541
542 // deadline context to ensure completion of background routines waited for
543 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
544 dctx, cancel := context.WithDeadline(context.Background(), deadline)
545
546 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
547
548 var wg sync.WaitGroup
549 wg.Add(1) // for the 1 go routine to finish
550 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
551 resource, entryID, &wg)
552 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
553 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
554 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
555 return err
556 }
557
558 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
559 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
560 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
561 pDevEntry.resetKvProcessingErrorIndication()
562 var wg2 sync.WaitGroup
563 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
564 wg2.Add(1)
565 // Removal of the gem id mapping represents the removal of the tech profile
566 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
567 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
568 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
569 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
570 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
571 return err
572 }
573 }
574 }
575 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
576 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530577 return nil
578}
579
mpagenkodff5dda2020-08-28 11:52:01 +0000580//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000581func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
khenaidoo7d3c5582021-08-11 18:09:44 -0400582 apOfFlowChanges *of.FlowChanges,
583 apOfGroupChanges *of.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300584 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000585 var retError error = nil
586 //Remove flows (always remove flows first - remove old and add new with same cookie may be part of the same request)
mpagenkodff5dda2020-08-28 11:52:01 +0000587 if apOfFlowChanges.ToRemove != nil {
588 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000589 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000590 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000591 "device-id": dh.deviceID})
592 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000593 continue
594 }
595 flowInPort := flow.GetInPort(flowItem)
596 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000597 logger.Warnw(ctx, "flow-remove inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000598 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
599 continue
600 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000601 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000602 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000604 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000605 continue
606 } else {
607 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530608 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000609 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
610 loUniPort = uniPort
611 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000612 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000613 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
614 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
615 flowInPort, dh.deviceID)
616 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000617 }
618 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000620 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000621 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000622 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000623 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000624 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000625 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000626 log.Fields{"device-id": dh.deviceID, "error": err})
627 retError = err
628 continue
629 //return err
630 } else { // if last setting succeeds, overwrite possibly previously set error
631 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000632 }
633 }
634 }
635 }
mpagenko01e726e2020-10-23 09:45:29 +0000636 if apOfFlowChanges.ToAdd != nil {
637 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
638 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000640 "device-id": dh.deviceID})
641 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
642 continue
643 }
644 flowInPort := flow.GetInPort(flowItem)
645 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Warnw(ctx, "flow-add inPort invalid: ignore and continuing on checking further flows", log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000647 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
648 continue
649 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
650 } else if flowInPort == dh.ponPortNumber {
651 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000652 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000653 "device-id": dh.deviceID, "inPort": flowInPort})
654 continue
655 } else {
656 // this is the relevant upstream flow
657 var loUniPort *onuUniPort
658 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
659 loUniPort = uniPort
660 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000661 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000662 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
663 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
664 flowInPort, dh.deviceID)
665 continue
666 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
667 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000668 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
669 // if not, we just throw some error here to have an indication about that, if we really need to support that
670 // then we would need to create some means to activate the internal stored flows
671 // after the device gets active automatically (and still with its dependency to the TechProfile)
672 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
673 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000674 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000676 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000677 return fmt.Errorf("improper device state on device %s", dh.deviceID)
678 }
679
mpagenko01e726e2020-10-23 09:45:29 +0000680 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000682 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
683 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300684 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000685 //try next flow after processing error
686 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000687 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000688 log.Fields{"device-id": dh.deviceID, "error": err})
689 retError = err
690 continue
691 //return err
692 } else { // if last setting succeeds, overwrite possibly previously set error
693 retError = nil
694 }
695 }
696 }
697 }
698 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000699}
700
Himani Chawla6d2ae152020-09-02 13:11:20 +0530701//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000702//following are the expected device states after this activity:
703//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
704// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000705func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
706 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000707
mpagenko900ee4b2020-10-12 11:56:34 +0000708 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000709 //note that disableDevice sequences in some 'ONU active' state may yield also
710 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000711 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000712 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000713 //disable-device shall be just a UNi/ONU-G related admin state setting
714 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000715
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000716 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000717 // disable UNI ports/ONU
718 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
719 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000720 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000721 } else { //LockStateFSM already init
722 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000723 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000724 }
725 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000726 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000727 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -0400728 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
729 DeviceId: dh.deviceID,
730 ConnStatus: voltha.ConnectStatus_REACHABLE,
731 OperStatus: voltha.OperStatus_UNKNOWN,
732 }); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +0000733 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000735 }
mpagenko01e726e2020-10-23 09:45:29 +0000736 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000737
738 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000739 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000740 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300741 }
742}
743
Himani Chawla6d2ae152020-09-02 13:11:20 +0530744//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000745func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
746 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000747
mpagenkoaa3afe92021-05-21 16:20:58 +0000748 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000749 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
750 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
751 // for real ONU's that should have nearly no influence
752 // Note that for real ONU's there is anyway a problematic situation with following sequence:
753 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
754 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
755 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000757
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000758 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000759 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000760 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000762 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000763 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000765 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300766}
767
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
769 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000770
dbainbri4d3a0dc2020-12-02 00:33:42 +0000771 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000772 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000774 return
775 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000777 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000779 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000781 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700782 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000783 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000784 }
Himani Chawla4d908332020-08-31 12:30:20 +0530785 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000786 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000787 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
788 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
789 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
790 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000791 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000793}
794
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
796 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000797
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000799 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000801 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700802 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000803 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000804 return
805 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000806 dh.pOnuTP.lockTpProcMutex()
807 defer dh.pOnuTP.unlockTpProcMutex()
808
mpagenko2dc896e2021-08-02 12:03:59 +0000809 pDevEntry.mutexPersOnuConfig.RLock()
810 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000811 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000812 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000814 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000815 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700816 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000817 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000818 return
819 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000820 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700821 techProfsFound := false
822 techProfInstLoadFailed := false
823outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000824 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000825 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
826 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000827 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000828 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000829 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000830 }
mpagenko2dc896e2021-08-02 12:03:59 +0000831 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
832 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
833 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
834 pDevEntry.mutexPersOnuConfig.RUnlock()
835 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700836 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800837 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700838 // Request the TpInstance again from the openolt adapter in case of reconcile
khenaidoo7d3c5582021-08-11 18:09:44 -0400839 iaTechTpInst, err := dh.getTechProfileInstanceFromParentAdapter(ctx,
840 dh.device.ProxyAddress.AdapterEndpoint,
841 &ic.TechProfileInstanceRequestMessage{
842 DeviceId: dh.device.Id,
843 TpInstancePath: uniData.PersTpPathMap[tpID],
844 ParentDeviceId: dh.parentID,
845 ParentPonPort: dh.device.ParentPortNo,
846 OnuId: dh.device.ProxyAddress.OnuId,
847 UniId: uint32(uniData.PersUniID),
848 })
Girish Gowdra50e56422021-06-01 16:46:04 -0700849 if err != nil || iaTechTpInst == nil {
850 logger.Errorw(ctx, "error fetching tp instance",
851 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
852 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
853 break outerLoop
854 }
855 var tpInst tech_profile.TechProfileInstance
856 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
khenaidoo7d3c5582021-08-11 18:09:44 -0400857 case *ic.TechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
Girish Gowdra50e56422021-06-01 16:46:04 -0700858 tpInst = *techTpInst.TpInstance
mpagenko2dc896e2021-08-02 12:03:59 +0000859 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
860 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700861 default: // do not support epon or other tech
mpagenko2dc896e2021-08-02 12:03:59 +0000862 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
863 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700864 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
865 break outerLoop
866 }
867
Girish Gowdra041dcb32020-11-16 16:54:30 -0800868 // deadline context to ensure completion of background routines waited for
869 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
870 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000872
Girish Gowdra041dcb32020-11-16 16:54:30 -0800873 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
874 var wg sync.WaitGroup
875 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700876 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800878 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000879 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700880 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
881 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800882 }
mpagenko2dc896e2021-08-02 12:03:59 +0000883 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000884 if len(uniData.PersFlowParams) != 0 {
885 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000886 }
mpagenko2dc896e2021-08-02 12:03:59 +0000887 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
888 persMutexLock = true
889 } // for all UNI entries from sOnuPersistentData
890 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
891 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000892 }
mpagenko2dc896e2021-08-02 12:03:59 +0000893
894 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
895 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
896}
897
898func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
899 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
900 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000901 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
902 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000903 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700904 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000905 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000906 return
907 }
mpagenko2dc896e2021-08-02 12:03:59 +0000908 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700909 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
910 dh.stopReconciling(ctx, false)
911 return
912 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000913 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
914 }
mpagenko2dc896e2021-08-02 12:03:59 +0000915 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000916 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
917 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000918 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700919 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000920 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000921 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922}
923
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
925 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000926
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000930 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700931 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000932 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000933 return
934 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000935
mpagenko2dc896e2021-08-02 12:03:59 +0000936 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000937 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko2dc896e2021-08-02 12:03:59 +0000938 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000940 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000941 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700942 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000943 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000944 return
945 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000946 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000947 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000948 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
949 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000950 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000951 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000952 continue
953 }
954 if len(uniData.PersTpPathMap) == 0 {
955 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
956 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000957 // It doesn't make sense to configure any flows if no TPs are available
958 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000959 }
mpagenko2dc896e2021-08-02 12:03:59 +0000960 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
961 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
962 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
963 pDevEntry.mutexPersOnuConfig.RUnlock()
964
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965 var uniPort *onuUniPort
966 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000968 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000969 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
970 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000971 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700972 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000973 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000974 return
975 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000976 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200977 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000978 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000979 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000980 for _, flowData := range uniData.PersFlowParams {
mpagenko2dc896e2021-08-02 12:03:59 +0000981 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
982 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200983 // If this is the last flow for the device we need to announce it the waiting
984 // chReconcilingFlowsFinished channel
985 if flowsProcessed == len(uniData.PersFlowParams)-1 {
986 lastFlowToReconcile = true
987 }
mpagenko01e726e2020-10-23 09:45:29 +0000988 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko7d14de12021-07-27 08:31:56 +0000989 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000990 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000991 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000992 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +0300993 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000994 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000995 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000996 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000998 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +0300999 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001 }
1002 }
mpagenko7d14de12021-07-27 08:31:56 +00001003 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001004 flowsProcessed++
mpagenko2dc896e2021-08-02 12:03:59 +00001005 } //for all flows of this UNI
1006 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1007 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1009 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001010 // this can't be used as global finished reconciling flag because
1011 // assumes is getting called before the state machines for the last flow is completed,
1012 // while this is not guaranteed.
1013 //dh.setReconcilingFlows(false)
mpagenko2dc896e2021-08-02 12:03:59 +00001014 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1015 } // for all UNI entries from sOnuPersistentData
1016 pDevEntry.mutexPersOnuConfig.RUnlock()
1017
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018 if !flowsFound {
1019 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1020 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001021 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001022 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001023 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001024 return
1025 }
1026 if dh.isSkipOnuConfigReconciling() {
1027 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001028 }
1029}
1030
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001031func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1032 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001033 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001034}
1035
dbainbri4d3a0dc2020-12-02 00:33:42 +00001036func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1037 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001038
dbainbri4d3a0dc2020-12-02 00:33:42 +00001039 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001040 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001041 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001042 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001043 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001044 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001045
1046 // deadline context to ensure completion of background routines waited for
1047 //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 +05301048 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001049 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001050
1051 pDevEntry.resetKvProcessingErrorIndication()
1052
1053 var wg sync.WaitGroup
1054 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1056 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001058 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001059 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001060}
1061
mpagenko15ff4a52021-03-02 10:09:20 +00001062//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1063// before this change here return like this was used:
1064// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1065//was and is called in background - error return does not make sense
1066func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1067 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1068 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001069 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001070 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001071 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001072 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301073 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001075 return
Himani Chawla4d908332020-08-31 12:30:20 +05301076 }
mpagenko01e726e2020-10-23 09:45:29 +00001077
1078 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001079 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001080
dbainbri4d3a0dc2020-12-02 00:33:42 +00001081 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001082 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001083 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1084 DeviceId: dh.deviceID,
1085 ConnStatus: voltha.ConnectStatus_REACHABLE,
1086 OperStatus: voltha.OperStatus_DISCOVERED,
1087 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001088 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001090 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001091 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001092 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001093 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001094 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001095 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001096 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1097 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1098 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1099 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001100}
1101
mpagenkoc8bba412021-01-15 15:38:44 +00001102//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko38662d02021-08-11 09:45:19 +00001103// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001104func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1105 apDownloadManager *adapterDownloadManager) error {
1106 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001107 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001108
1109 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001110 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1111 if pDevEntry == nil {
1112 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1113 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1114 }
1115
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001116 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001117 var inactiveImageID uint16
1118 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1119 dh.lockUpgradeFsm.Lock()
1120 defer dh.lockUpgradeFsm.Unlock()
1121 if dh.pOnuUpradeFsm == nil {
1122 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1123 if err == nil {
1124 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1125 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1126 "device-id": dh.deviceID, "error": err})
1127 }
1128 } else {
1129 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001130 "device-id": dh.deviceID, "error": err})
1131 }
mpagenko15ff4a52021-03-02 10:09:20 +00001132 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1133 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00001134 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1135 //no effort spent anymore for the old API to automatically cancel and restart the download
1136 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001137 }
mpagenko15ff4a52021-03-02 10:09:20 +00001138 } else {
1139 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1140 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001141 }
1142 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001143 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1144 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001145 }
1146 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001147}
1148
mpagenkoc26d4c02021-05-06 14:27:57 +00001149//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1150// after the OnuImage has been downloaded to the adapter, called in background
1151func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1152 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1153
1154 var err error
1155 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1156 if pDevEntry == nil {
1157 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1158 return
1159 }
1160
1161 var inactiveImageID uint16
1162 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1163 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1164 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
mpagenko38662d02021-08-11 09:45:19 +00001165
1166 dh.lockUpgradeFsm.RLock()
1167 lopOnuUpradeFsm := dh.pOnuUpradeFsm
1168 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
1169 dh.lockUpgradeFsm.RUnlock()
1170 if lopOnuUpradeFsm != nil {
1171 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1172 // abort the current processing, running upgrades are always aborted by newer request
1173 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1174 //flush the remove upgradeFsmChan channel
1175 select {
1176 case <-dh.upgradeFsmChan:
1177 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1178 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001179 }
mpagenko38662d02021-08-11 09:45:19 +00001180 lopOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1181 select {
1182 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1183 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1184 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1185 return
1186 case <-dh.upgradeFsmChan:
1187 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1188 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001189 }
mpagenko38662d02021-08-11 09:45:19 +00001190
1191 //here it can be assumed that no running upgrade processing exists (anymore)
1192 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1193 // but none yet defined
1194 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1195 if err == nil {
1196 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1197 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1198 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001199 "device-id": dh.deviceID, "error": err})
1200 return
1201 }
mpagenko38662d02021-08-11 09:45:19 +00001202 } else {
1203 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1204 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001205 }
1206 return
1207 }
1208 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1209 "device-id": dh.deviceID, "error": err})
1210}
1211
1212//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001213func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1214 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001215 var err error
1216 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1217 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1218 // 2.) activation of the inactive image
1219
1220 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1221 if pDevEntry == nil {
1222 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001223 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001224 }
1225 dh.lockUpgradeFsm.RLock()
1226 if dh.pOnuUpradeFsm != nil {
1227 dh.lockUpgradeFsm.RUnlock()
khenaidoo7d3c5582021-08-11 18:09:44 -04001228 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001229 if getErr != nil || onuVolthaDevice == nil {
1230 logger.Errorw(ctx, "Failed to fetch Onu device for image activation", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001231 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001232 }
1233 // use the OnuVendor identification from this device for the internal unique name
1234 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001235 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001236 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001237 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001238 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1239 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001240 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001241 }
mpagenko183647c2021-06-08 15:25:04 +00001242 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1243 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001244 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001245 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001246 } //else
1247 dh.lockUpgradeFsm.RUnlock()
1248
1249 // 2.) check if requested image-version equals the inactive one and start its activation
1250 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1251 var inactiveImageID uint16
1252 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1253 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1254 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001255 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001256 }
1257 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1258 if err == nil {
1259 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1260 inactiveImageID, aCommitRequest); err != nil {
1261 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1262 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001263 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001264 }
1265 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1266 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001267 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001268 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001269 } //else
1270 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1271 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001272 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001273}
1274
1275//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001276func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1277 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001278 var err error
1279 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1280 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1281 // 2.) commitment of the active image
1282
1283 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1284 if pDevEntry == nil {
1285 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001286 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 }
1288 dh.lockUpgradeFsm.RLock()
1289 if dh.pOnuUpradeFsm != nil {
1290 dh.lockUpgradeFsm.RUnlock()
khenaidoo7d3c5582021-08-11 18:09:44 -04001291 onuVolthaDevice, getErr := dh.getDeviceFromCore(ctx, dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001292 if getErr != nil || onuVolthaDevice == nil {
1293 logger.Errorw(ctx, "Failed to fetch Onu device for image commitment", log.Fields{"device-id": dh.deviceID, "err": getErr})
mpagenko183647c2021-06-08 15:25:04 +00001294 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001295 }
1296 // use the OnuVendor identification from this device for the internal unique name
1297 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko38662d02021-08-11 09:45:19 +00001298 // 1.) check a started upgrade process and relay the commitment request to it
1299 // the running upgrade may be based either on the imageIdentifier (started from download)
1300 // or on the imageVersion (started from pure activation)
1301 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1302 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001303 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1304 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001305 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001306 }
mpagenko183647c2021-06-08 15:25:04 +00001307 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1308 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko38662d02021-08-11 09:45:19 +00001309 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001310 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001311 } //else
1312 dh.lockUpgradeFsm.RUnlock()
1313
mpagenko183647c2021-06-08 15:25:04 +00001314 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001315 var activeImageID uint16
1316 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1317 logger.Errorw(ctx, "get active image failed", log.Fields{
1318 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001319 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001320 }
1321 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1322 if err == nil {
1323 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1324 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1325 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001326 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001327 }
1328 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1329 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko38662d02021-08-11 09:45:19 +00001330 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001331 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001332 } //else
1333 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1334 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001335 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001336}
1337
mpagenkoaa3afe92021-05-21 16:20:58 +00001338func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko38662d02021-08-11 09:45:19 +00001339 aVersion string) *voltha.ImageState {
1340 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001341 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00001342 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001343 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001344 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1345 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1346 if aVersion == dh.pLastUpgradeImageState.Version {
1347 pImageState = dh.pLastUpgradeImageState
1348 } else { //state request for an image version different from last processed image version
1349 pImageState = &voltha.ImageState{
1350 Version: aVersion,
1351 //we cannot state something concerning this version
1352 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1353 Reason: voltha.ImageState_NO_ERROR,
1354 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1355 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001356 }
1357 }
mpagenko38662d02021-08-11 09:45:19 +00001358 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001359}
1360
1361func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1362 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1363 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001364 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001365 dh.lockUpgradeFsm.RLock()
1366 if dh.pOnuUpradeFsm != nil {
mpagenko38662d02021-08-11 09:45:19 +00001367 if aVersion == dh.pOnuUpradeFsm.GetImageVersion(ctx) {
1368 // so then we cancel the upgrade operation
1369 // but before we still request the actual ImageState (which should not change with the cancellation)
1370 pDeviceImageState.ImageState.ImageState = dh.pOnuUpradeFsm.GetSpecificImageState(ctx)
1371 dh.lockUpgradeFsm.RUnlock()
1372 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1373 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1374 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1375 } else { //nothing to cancel, states unknown
1376 dh.lockUpgradeFsm.RUnlock()
1377 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1378 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1379 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1380 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001381 } else {
mpagenko38662d02021-08-11 09:45:19 +00001382 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1383 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1384 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1385 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1386 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1387 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001388 dh.lockUpgradeFsm.RUnlock()
1389 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1390 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko38662d02021-08-11 09:45:19 +00001391 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1392 //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 +00001393 }
1394}
1395
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001396func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1397
1398 var onuImageStatus *OnuImageStatus
1399
1400 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1401 if pDevEntry != nil {
1402 onuImageStatus = NewOnuImageStatus(pDevEntry)
1403 pDevEntry.mutexOnuImageStatus.Lock()
1404 pDevEntry.pOnuImageStatus = onuImageStatus
1405 pDevEntry.mutexOnuImageStatus.Unlock()
1406
1407 } else {
1408 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1409 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1410 }
1411 images, err := onuImageStatus.getOnuImageStatus(ctx)
1412 pDevEntry.mutexOnuImageStatus.Lock()
1413 pDevEntry.pOnuImageStatus = nil
1414 pDevEntry.mutexOnuImageStatus.Unlock()
1415 return images, err
1416}
1417
Himani Chawla6d2ae152020-09-02 13:11:20 +05301418// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001419// #####################################################################################
1420
1421// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301422// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001423
dbainbri4d3a0dc2020-12-02 00:33:42 +00001424func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1425 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 +00001426}
1427
1428// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001430
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001432 var err error
1433
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001434 // populate what we know. rest comes later after mib sync
1435 dh.device.Root = false
1436 dh.device.Vendor = "OpenONU"
1437 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001438 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001439 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001440
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001441 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001442
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001443 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001445 if err := dh.updateDeviceInCore(ctx, dh.device); err != nil {
1446 logger.Errorw(ctx, "device-update-failed", log.Fields{"device-id": dh.device.Id, "error": err})
1447 }
Himani Chawlac07fda02020-12-09 16:21:21 +05301448 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001449 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001450 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001451 log.Fields{"device-id": dh.deviceID})
1452 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001453
Himani Chawla4d908332020-08-31 12:30:20 +05301454 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001455 dh.ponPortNumber = dh.device.ParentPortNo
1456
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001457 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1458 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1459 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001461 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301462 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001463
1464 /*
1465 self._pon = PonPort.create(self, self._pon_port_number)
1466 self._pon.add_peer(self.parent_id, self._pon_port_number)
1467 self.logger.debug('adding-pon-port-to-agent',
1468 type=self._pon.get_port().type,
1469 admin_state=self._pon.get_port().admin_state,
1470 oper_status=self._pon.get_port().oper_status,
1471 )
1472 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001473 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001474 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001475 var ponPortNo uint32 = 1
1476 if dh.ponPortNumber != 0 {
1477 ponPortNo = dh.ponPortNumber
1478 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001479
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001480 pPonPort := &voltha.Port{
khenaidoo7d3c5582021-08-11 18:09:44 -04001481 DeviceId: dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001482 PortNo: ponPortNo,
1483 Label: fmt.Sprintf("pon-%d", ponPortNo),
1484 Type: voltha.Port_PON_ONU,
1485 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301486 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001487 PortNo: ponPortNo}}, // Peer port is parent's port number
1488 }
khenaidoo7d3c5582021-08-11 18:09:44 -04001489 if err = dh.createPortInCore(ctx, pPonPort); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001490 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001491 e.Cancel(err)
1492 return
1493 }
1494 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001495 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001496 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001498}
1499
1500// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001501func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001502
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001504 var err error
1505 /*
1506 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1507 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1508 return nil
1509 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1511 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001512 e.Cancel(err)
1513 return
1514 }
1515
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001516 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001518 // reconcilement will be continued after mib download is done
1519 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001520
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001521 /*
1522 ############################################################################
1523 # Setup Alarm handler
1524 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1525 device.serial_number)
1526 ############################################################################
1527 # Setup PM configuration for this device
1528 # Pass in ONU specific options
1529 kwargs = {
1530 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1531 'heartbeat': self.heartbeat,
1532 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1533 }
1534 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1535 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1536 self.logical_device_id, device.serial_number,
1537 grouped=True, freq_override=False, **kwargs)
1538 pm_config = self._pm_metrics.make_proto()
1539 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1540 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1541 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1542
1543 # Note, ONU ID and UNI intf set in add_uni_port method
1544 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1545 ani_ports=[self._pon])
1546
1547 # Code to Run OMCI Test Action
1548 kwargs_omci_test_action = {
1549 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1550 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1551 }
1552 serial_number = device.serial_number
1553 self._test_request = OmciTestRequest(self.core_proxy,
1554 self.omci_agent, self.device_id,
1555 AniG, serial_number,
1556 self.logical_device_id,
1557 exclusive=False,
1558 **kwargs_omci_test_action)
1559
1560 self.enabled = True
1561 else:
1562 self.logger.info('onu-already-activated')
1563 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001564
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001566}
1567
1568// doStateConnected get the device info and update to voltha core
1569// for comparison of the original method (not that easy to uncomment): compare here:
1570// voltha-openolt-adapter/adaptercore/device_handler.go
1571// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301575 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001576 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001578}
1579
1580// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001582
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301584 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001585 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587
1588 /*
1589 // Synchronous call to update device state - this method is run in its own go routine
1590 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1591 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001592 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 +00001593 return err
1594 }
1595 return nil
1596 */
1597}
1598
1599// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001601
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001603 var err error
1604
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001605 device := dh.device
1606 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001607 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001609 e.Cancel(err)
1610 return
1611 }
1612
1613 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615 /*
1616 // Update the all ports state on that device to disable
1617 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001618 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001619 return er
1620 }
1621
1622 //Update the device oper state and connection status
1623 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1624 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1625 dh.device = cloned
1626
1627 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001628 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001629 return er
1630 }
1631
1632 //get the child device for the parent device
1633 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1634 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001635 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 return err
1637 }
1638 for _, onuDevice := range onuDevices.Items {
1639
1640 // Update onu state as down in onu adapter
1641 onuInd := oop.OnuIndication{}
1642 onuInd.OperState = "down"
1643 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1644 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1645 if er != nil {
1646 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001647 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648 //Do not return here and continue to process other ONUs
1649 }
1650 }
1651 // * Discovered ONUs entries need to be cleared , since after OLT
1652 // is up, it starts sending discovery indications again* /
1653 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001654 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001655 return nil
1656 */
Himani Chawla4d908332020-08-31 12:30:20 +05301657 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001658 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001660}
1661
Himani Chawla6d2ae152020-09-02 13:11:20 +05301662// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001663// #################################################################################
1664
1665// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301666// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001667
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001668//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001670 dh.lockDevice.RLock()
1671 pOnuDeviceEntry := dh.pOnuOmciDevice
1672 if aWait && pOnuDeviceEntry == nil {
1673 //keep the read sema short to allow for subsequent write
1674 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001676 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1677 // so it might be needed to wait here for that event with some timeout
1678 select {
1679 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001681 return nil
1682 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001684 // if written now, we can return the written value without sema
1685 return dh.pOnuOmciDevice
1686 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001687 }
mpagenko3af1f032020-06-10 08:53:41 +00001688 dh.lockDevice.RUnlock()
1689 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001690}
1691
Himani Chawla6d2ae152020-09-02 13:11:20 +05301692//setOnuDeviceEntry sets the ONU device entry within the handler
1693func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001694 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001695 dh.lockDevice.Lock()
1696 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001697 dh.pOnuOmciDevice = apDeviceEntry
1698 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001699 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301700 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001701 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001702}
1703
Himani Chawla6d2ae152020-09-02 13:11:20 +05301704//addOnuDeviceEntry creates a new ONU device or returns the existing
1705func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001707
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001709 if deviceEntry == nil {
1710 /* costum_me_map in python code seems always to be None,
1711 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1712 /* also no 'clock' argument - usage open ...*/
1713 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001714 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001715 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001716 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301717 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001718 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001719 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001720 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001721 // fire deviceEntry ready event to spread to possibly waiting processing
1722 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001724 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001726 }
1727 // might be updated with some error handling !!!
1728 return nil
1729}
1730
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1732 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001733 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1734
1735 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001736
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001738 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001740 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1741 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001742 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 if err := dh.storePersistentData(ctx); err != nil {
1744 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001745 log.Fields{"device-id": dh.deviceID, "err": err})
1746 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001747 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001748 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001749
1750 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1751 DeviceId: dh.deviceID,
1752 OperStatus: voltha.OperStatus_ACTIVATING,
1753 ConnStatus: voltha.ConnectStatus_REACHABLE,
1754 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001755 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001757 }
1758 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001760 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001761
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001762 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001763 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001764 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001765 logger.Debugw(ctx, "reconciling - uni-ports were not unlocked before adapter restart - resume with a normal start-up",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001766 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001767 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001768 } else {
1769 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001770 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001771 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001772 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1773 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1774 // in python code it looks as the started onu_omci_device might have been updated with some new instance state of the core device
mpagenkoaf801632020-07-03 10:00:42 +00001775 // but I would not know why, and the go code anyway does not work with the device directly anymore in the OnuDeviceEntry
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001776 // so let's just try to keep it simple ...
1777 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001778 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001779 if err != nil || device == nil {
1780 //TODO: needs to handle error scenarios
1781 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1782 return errors.New("Voltha Device not found")
1783 }
1784 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001785
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001787 return err
mpagenko3af1f032020-06-10 08:53:41 +00001788 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001789
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001790 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001791
1792 /* this might be a good time for Omci Verify message? */
1793 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001795 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001796 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001798
1799 /* give the handler some time here to wait for the OMCi verification result
1800 after Timeout start and try MibUpload FSM anyway
1801 (to prevent stopping on just not supported OMCI verification from ONU) */
1802 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001803 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001805 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001807 }
1808
1809 /* In py code it looks earlier (on activate ..)
1810 # Code to Run OMCI Test Action
1811 kwargs_omci_test_action = {
1812 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1813 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1814 }
1815 serial_number = device.serial_number
1816 self._test_request = OmciTestRequest(self.core_proxy,
1817 self.omci_agent, self.device_id,
1818 AniG, serial_number,
1819 self.logical_device_id,
1820 exclusive=False,
1821 **kwargs_omci_test_action)
1822 ...
1823 # Start test requests after a brief pause
1824 if not self._test_request_started:
1825 self._test_request_started = True
1826 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1827 reactor.callLater(tststart, self._test_request.start_collector)
1828
1829 */
1830 /* which is then: in omci_test_request.py : */
1831 /*
1832 def start_collector(self, callback=None):
1833 """
1834 Start the collection loop for an adapter if the frequency > 0
1835
1836 :param callback: (callable) Function to call to collect PM data
1837 """
1838 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1839 if callback is None:
1840 callback = self.perform_test_omci
1841
1842 if self.lc is None:
1843 self.lc = LoopingCall(callback)
1844
1845 if self.default_freq > 0:
1846 self.lc.start(interval=self.default_freq / 10)
1847
1848 def perform_test_omci(self):
1849 """
1850 Perform the initial test request
1851 """
1852 ani_g_entities = self._device.configuration.ani_g_entities
1853 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1854 is not None else None
1855 self._entity_id = ani_g_entities_ids[0]
1856 self.logger.info('perform-test', entity_class=self._entity_class,
1857 entity_id=self._entity_id)
1858 try:
1859 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1860 result = yield self._device.omci_cc.send(frame)
1861 if not result.fields['omci_message'].fields['success_code']:
1862 self.logger.info('Self-Test Submitted Successfully',
1863 code=result.fields[
1864 'omci_message'].fields['success_code'])
1865 else:
1866 raise TestFailure('Test Failure: {}'.format(
1867 result.fields['omci_message'].fields['success_code']))
1868 except TimeoutError as e:
1869 self.deferred.errback(failure.Failure(e))
1870
1871 except Exception as e:
1872 self.logger.exception('perform-test-Error', e=e,
1873 class_id=self._entity_class,
1874 entity_id=self._entity_id)
1875 self.deferred.errback(failure.Failure(e))
1876
1877 */
1878
1879 // PM related heartbeat??? !!!TODO....
1880 //self._heartbeat.enabled = True
1881
mpagenko1cc3cb42020-07-27 15:24:38 +00001882 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1883 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1884 * 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 +05301885 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001886 */
1887 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001888 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001889 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001890 if pMibUlFsm.Is(ulStDisabled) {
1891 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001892 logger.Errorw(ctx, "MibSyncFsm: Can't go to state starting", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001893 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301894 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301896 //Determine ONU status and start/re-start MIB Synchronization tasks
1897 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001898 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301899 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 logger.Errorw(ctx, "MibSyncFsm: Can't go to state resetting_mib", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001901 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001902 }
Himani Chawla4d908332020-08-31 12:30:20 +05301903 } else {
1904 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 logger.Errorw(ctx, "MibSyncFsm: Can't go to state examine_mds", log.Fields{"device-id": dh.deviceID, "err": err})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001906 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301907 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001909 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001910 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001911 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001912 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001913 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001914 }
1915 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001917 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001918 }
1919 return nil
1920}
1921
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001923 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001924 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001925 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001927
mpagenko900ee4b2020-10-12 11:56:34 +00001928 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1929 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1930 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001931 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001933 log.Fields{"device-id": dh.deviceID, "error": err})
1934 // abort: system behavior is just unstable ...
1935 return err
1936 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001937 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 _ = 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 +00001939
1940 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1941 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1942 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001944 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001946 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001949
1950 //TODO!!! remove existing traffic profiles
1951 /* from py code, if TP's exist, remove them - not yet implemented
1952 self._tp = dict()
1953 # Let TP download happen again
1954 for uni_id in self._tp_service_specific_task:
1955 self._tp_service_specific_task[uni_id].clear()
1956 for uni_id in self._tech_profile_download_done:
1957 self._tech_profile_download_done[uni_id].clear()
1958 */
1959
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001961
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001962 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001963
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001965 // abort: system behavior is just unstable ...
1966 return err
1967 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001969 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04001970 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
1971 DeviceId: dh.deviceID,
1972 ConnStatus: voltha.ConnectStatus_UNREACHABLE,
1973 OperStatus: voltha.OperStatus_DISCOVERED,
1974 }); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001975 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001977 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001978 // abort: system behavior is just unstable ...
1979 return err
1980 }
1981 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001983 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001984 return nil
1985}
1986
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001987func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001988 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1989 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1990 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1991 // and using the stop/reset event should never harm
1992
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001994 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001996 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1997 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001998 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00001999 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002000 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002001 pDevEntry.mutexOnuImageStatus.RLock()
2002 if pDevEntry.pOnuImageStatus != nil {
2003 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2004 }
2005 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002006
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002007 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002008 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002009 }
2010 //MibDownload may run
2011 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2012 if pMibDlFsm != nil {
2013 _ = pMibDlFsm.Event(dlEvReset)
2014 }
2015 //port lock/unlock FSM's may be active
2016 if dh.pUnlockStateFsm != nil {
2017 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2018 }
2019 if dh.pLockStateFsm != nil {
2020 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2021 }
2022 //techProfile related PonAniConfigFsm FSM may be active
2023 if dh.pOnuTP != nil {
2024 // should always be the case here
2025 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2026 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002027 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002028 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002029 }
mpagenko900ee4b2020-10-12 11:56:34 +00002030 }
2031 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002032 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002033 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002034 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2035 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002036 dh.lockVlanConfig.RUnlock()
2037 //reset of all Fsm is always accompanied by global persistency data removal
2038 // no need to remove specific data
2039 pVlanFilterFsm.RequestClearPersistency(false)
2040 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002041 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002042 } else {
2043 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002044 }
2045 }
2046 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002047 if dh.getCollectorIsRunning() {
2048 // Stop collector routine
2049 dh.stopCollector <- true
2050 }
Himani Chawla1472c682021-03-17 17:11:14 +05302051 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302052 dh.stopAlarmManager <- true
2053 }
Girish Gowdra10123c02021-08-30 11:52:06 -07002054 if dh.pSelfTestHdlr.GetSelfTestHandlerIsRunning() {
2055 dh.pSelfTestHdlr.stopSelfTestModule <- true
2056 }
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302057
mpagenko80622a52021-02-09 16:53:23 +00002058 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002059 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002060 dh.lockUpgradeFsm.RLock()
mpagenko38662d02021-08-11 09:45:19 +00002061 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2062 //lockUpgradeFsm must be release before cancellation as this may implicitly request removeOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002063 dh.lockUpgradeFsm.RUnlock()
mpagenko38662d02021-08-11 09:45:19 +00002064 if lopOnuUpradeFsm != nil {
2065 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2066 }
mpagenko80622a52021-02-09 16:53:23 +00002067
mpagenko7d6bb022021-03-11 15:07:55 +00002068 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002069 return nil
2070}
2071
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2073 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 +05302074
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002075 // store persistent data collected during MIB upload processing
2076 if err := dh.storePersistentData(ctx); err != nil {
2077 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2078 log.Fields{"device-id": dh.deviceID, "err": err})
2079 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002080 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002081 dh.addAllUniPorts(ctx)
2082
mpagenkoa40e99a2020-11-17 13:50:39 +00002083 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2084 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2085 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2086 * disable/enable toggling here to allow traffic
2087 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2088 * like the py comment says:
2089 * # start by locking all the unis till mib sync and initial mib is downloaded
2090 * # this way we can capture the port down/up events when we are ready
2091 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302092
mpagenkoa40e99a2020-11-17 13:50:39 +00002093 // Init Uni Ports to Admin locked state
2094 // *** should generate UniLockStateDone event *****
2095 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002097 } else { //LockStateFSM already init
2098 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002100 }
2101}
2102
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2104 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302105 /* Mib download procedure -
2106 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2107 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002108 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002109 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002110 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002111 return
2112 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302113 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2114 if pMibDlFsm != nil {
2115 if pMibDlFsm.Is(dlStDisabled) {
2116 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 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 +05302118 // maybe try a FSM reset and then again ... - TODO!!!
2119 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302121 // maybe use more specific states here for the specific download steps ...
2122 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002123 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302124 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302126 //Begin MIB data download (running autonomously)
2127 }
2128 }
2129 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002131 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302132 // maybe try a FSM reset and then again ... - TODO!!!
2133 }
2134 /***** Mib download started */
2135 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302137 }
2138}
2139
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2141 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002143 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002145 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002146 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2147 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2148 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2149 dh.checkOnOnuImageCommit(ctx)
khenaidoo7d3c5582021-08-11 18:09:44 -04002150 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2151 DeviceId: dh.deviceID,
2152 ConnStatus: voltha.ConnectStatus_REACHABLE,
2153 OperStatus: voltha.OperStatus_ACTIVE,
2154 }); err != nil {
Himani Chawla26e555c2020-08-31 12:30:20 +05302155 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302157 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302159 }
2160 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302162 log.Fields{"device-id": dh.deviceID})
2163 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002164 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002165
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002166 if !dh.getCollectorIsRunning() {
2167 // Start PM collector routine
2168 go dh.startCollector(ctx)
2169 }
2170 if !dh.getAlarmManagerIsRunning(ctx) {
2171 go dh.startAlarmManager(ctx)
2172 }
2173
Girish Gowdrae0140f02021-02-02 16:55:09 -08002174 // Initialize classical L2 PM Interval Counters
2175 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2176 // There is no way we should be landing here, but if we do then
2177 // there is nothing much we can do about this other than log error
2178 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2179 }
2180
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002181 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002182
2183 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2184 if pDevEntry == nil {
2185 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2186 return
2187 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002188 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002189 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002191 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2192 log.Fields{"device-id": dh.deviceID})
2193 go dh.reconcileDeviceTechProf(ctx)
2194 // reconcilement will be continued after ani config is done
2195 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002196 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002197 // *** should generate UniUnlockStateDone event *****
2198 if dh.pUnlockStateFsm == nil {
2199 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2200 } else { //UnlockStateFSM already init
2201 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2202 dh.runUniLockFsm(ctx, false)
2203 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302204 }
2205}
2206
dbainbri4d3a0dc2020-12-02 00:33:42 +00002207func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2208 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302209
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002210 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002212 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2214 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002215 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002216 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002217 return
2218 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002219 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002220 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002221 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 if err := dh.storePersistentData(ctx); err != nil {
2223 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002224 log.Fields{"device-id": dh.deviceID, "err": err})
2225 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302226 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Debugw(ctx, "reconciling - don't notify core that onu went to active but trigger tech profile config",
Himani Chawla26e555c2020-08-31 12:30:20 +05302228 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002230 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302231 }
2232}
2233
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2235 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002236 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002237
2238 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2239 DeviceId: dh.deviceID,
2240 ConnStatus: voltha.ConnectStatus_REACHABLE,
2241 OperStatus: voltha.OperStatus_UNKNOWN,
2242 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002243 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002245 }
2246
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002248 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002250
2251 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002253
dbainbri4d3a0dc2020-12-02 00:33:42 +00002254 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002255 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002257 return
2258 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002259 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002260 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002261 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 if err := dh.storePersistentData(ctx); err != nil {
2263 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002264 log.Fields{"device-id": dh.deviceID, "err": err})
2265 }
mpagenko900ee4b2020-10-12 11:56:34 +00002266}
2267
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2269 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002270 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04002271 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
2272 DeviceId: dh.deviceID,
2273 ConnStatus: voltha.ConnectStatus_REACHABLE,
2274 OperStatus: voltha.OperStatus_ACTIVE,
2275 }); err != nil {
mpagenko900ee4b2020-10-12 11:56:34 +00002276 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002277 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002278 }
2279
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002281 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002282 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002283 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002284
2285 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002287
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002289 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002291 return
2292 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002293 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002294 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002295 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 if err := dh.storePersistentData(ctx); err != nil {
2297 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002298 log.Fields{"device-id": dh.deviceID, "err": err})
2299 }
mpagenko900ee4b2020-10-12 11:56:34 +00002300}
2301
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002303 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002304 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002305 // attention: the device reason update is done based on ONU-UNI-Port related activity
2306 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002307 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002308 // which may be the case from some previous actvity even on this UNI Port (but also other UNI ports)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002309 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302310 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002311 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002313 }
2314 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002316 // attention: the device reason update is done based on ONU-UNI-Port related activity
2317 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002318 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002319 // which may be the case from some previous actvity even on this ONU port (but also other UNI ports)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002321 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002322 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302323}
2324
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2326 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002327 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302328 // attention: the device reason update is done based on ONU-UNI-Port related activity
2329 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302330
mpagenkof1fc3862021-02-16 10:09:52 +00002331 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002332 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002333 // which may be the case from some previous actvity on another UNI Port of the ONU
2334 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002335 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2336 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002337 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002338 }
2339 }
2340 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002341 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002342 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002344 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302345 }
mpagenkof1fc3862021-02-16 10:09:52 +00002346
2347 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2348 //events that request KvStore write
2349 if err := dh.storePersistentData(ctx); err != nil {
2350 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2351 log.Fields{"device-id": dh.deviceID, "err": err})
2352 }
2353 } else {
2354 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2355 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002356 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302357}
2358
Himani Chawla6d2ae152020-09-02 13:11:20 +05302359//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002360func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302361 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002362 case MibDatabaseSync:
2363 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002365 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002366 case UniLockStateDone:
2367 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002369 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002370 case MibDownloadDone:
2371 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002372 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002373 }
2374 case UniUnlockStateDone:
2375 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002376 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002377 }
mpagenko900ee4b2020-10-12 11:56:34 +00002378 case UniEnableStateDone:
2379 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002381 }
2382 case UniDisableStateDone:
2383 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002384 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002385 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002386 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002387 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002388 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002389 }
mpagenkof1fc3862021-02-16 10:09:52 +00002390 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002391 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002392 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002393 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002394 default:
2395 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002396 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002397 }
2398 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002399}
2400
dbainbri4d3a0dc2020-12-02 00:33:42 +00002401func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002402 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302404 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002405 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002406 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002407 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302408 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002409 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002410 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002412 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002413 //store UniPort with the System-PortNumber key
2414 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002415 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002416 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2418 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002419 } //error logging already within UniPort method
2420 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002422 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002423 }
2424 }
2425}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002426
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002427func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2428 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2429 if pDevEntry == nil {
2430 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2431 return
2432 }
2433 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2434 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2435 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2436 for _, mgmtEntityID := range pptpInstKeys {
2437 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2438 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2439 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2440 i++
2441 }
2442 } else {
2443 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2444 }
2445 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2446 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2447 for _, mgmtEntityID := range veipInstKeys {
2448 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2449 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2450 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2451 i++
2452 }
2453 } else {
2454 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2455 }
ozgecanetsia124d9732021-09-16 14:31:57 +03002456 if potsInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2457 ctx, me.PhysicalPathTerminationPointPotsUniClassID); len(potsInstKeys) > 0 {
2458 for _, mgmtEntityID := range potsInstKeys {
2459 logger.Debugw(ctx, "Add PPTP Pots UNI for MIB-stored instance:", log.Fields{
2460 "device-id": dh.deviceID, "PPTP Pots UNI EntityID": mgmtEntityID})
2461 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTPPots)
2462 i++
2463 }
2464 } else {
2465 logger.Debugw(ctx, "No PPTP Pots UNI instances found", log.Fields{"device-id": dh.deviceID})
2466 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002467 if i == 0 {
2468 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2469 }
2470}
2471
mpagenko3af1f032020-06-10 08:53:41 +00002472// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002474 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302475 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002476 // with following remark:
2477 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2478 // # load on the core
2479
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002480 // 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 +00002481
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002482 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002483 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002484 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002485 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302486 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002487 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002488 //maybe also use getter functions on uniPort - perhaps later ...
khenaidoo7d3c5582021-08-11 18:09:44 -04002489 go func(port *onuUniPort) {
2490 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
2491 DeviceId: dh.deviceID,
2492 PortType: voltha.Port_ETHERNET_UNI,
2493 PortNo: port.portNo,
2494 OperStatus: port.operState,
2495 }); err != nil {
2496 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.portNo, "device-id": dh.deviceID})
2497 }
2498 }(uniPort)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002499 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002501 }
mpagenko3af1f032020-06-10 08:53:41 +00002502 }
2503 }
2504}
2505
2506// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002507func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002508 // compare enableUniPortStateUpdate() above
2509 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2510 for uniNo, uniPort := range dh.uniEntityMap {
2511 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002512
2513 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002514 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302515 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002516 if !dh.isReconciling() {
2517 //maybe also use getter functions on uniPort - perhaps later ...
khenaidoo7d3c5582021-08-11 18:09:44 -04002518 go func(port *onuUniPort) {
2519 if err := dh.updatePortStateInCore(ctx, &ic.PortState{
2520 DeviceId: dh.deviceID,
2521 PortType: voltha.Port_ETHERNET_UNI,
2522 PortNo: port.portNo,
2523 OperStatus: port.operState,
2524 }); err != nil {
2525 logger.Errorw(ctx, "port-state-update-failed", log.Fields{"error": err, "port-no": uniPort.portNo, "device-id": dh.deviceID})
2526 }
2527 }(uniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002528 } else {
2529 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2530 }
2531
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002532 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002533 }
2534}
2535
2536// ONU_Active/Inactive announcement on system KAFKA bus
2537// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002538func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002539 var de voltha.DeviceEvent
2540 eventContext := make(map[string]string)
2541 //Populating event context
2542 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
khenaidoo7d3c5582021-08-11 18:09:44 -04002543 parentDevice, err := dh.getDeviceFromCore(ctx, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002544 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302546 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002547 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 +00002548 }
2549 oltSerialNumber := parentDevice.SerialNumber
2550
2551 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2552 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2553 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302554 eventContext["olt-serial-number"] = oltSerialNumber
2555 eventContext["device-id"] = aDeviceID
2556 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002557 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2558 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2559 deviceEntry.mutexPersOnuConfig.RLock()
2560 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2561 deviceEntry.mutexPersOnuConfig.RUnlock()
2562 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2563 deviceEntry.mutexPersOnuConfig.RLock()
2564 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2565 deviceEntry.mutexPersOnuConfig.RUnlock()
2566 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2567 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2568 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2569 } else {
2570 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2571 log.Fields{"device-id": aDeviceID})
2572 return
2573 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002574
2575 /* Populating device event body */
2576 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302577 de.ResourceId = aDeviceID
2578 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002579 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2580 de.Description = fmt.Sprintf("%s Event - %s - %s",
2581 cEventObjectType, cOnuActivatedEvent, "Raised")
2582 } else {
2583 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2584 de.Description = fmt.Sprintf("%s Event - %s - %s",
2585 cEventObjectType, cOnuActivatedEvent, "Cleared")
2586 }
2587 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002588 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2589 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302590 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002591 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002592 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302593 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002594}
2595
Himani Chawla4d908332020-08-31 12:30:20 +05302596// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002597func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002598 chLSFsm := make(chan Message, 2048)
2599 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302600 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002601 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002602 sFsmName = "LockStateFSM"
2603 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002604 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002605 sFsmName = "UnLockStateFSM"
2606 }
mpagenko3af1f032020-06-10 08:53:41 +00002607
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002609 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002610 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002611 return
2612 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002614 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302616 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002617 dh.pLockStateFsm = pLSFsm
2618 } else {
2619 dh.pUnlockStateFsm = pLSFsm
2620 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002623 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002624 }
2625}
2626
2627// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002628func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002629 /* Uni Port lock/unlock procedure -
2630 ***** should run via 'adminDone' state and generate the argument requested event *****
2631 */
2632 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302633 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002634 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2635 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2636 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002637 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302638 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002639 }
2640 } else {
2641 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2642 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2643 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002644 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302645 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002646 }
2647 }
2648 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002649 if pLSStatemachine.Is(uniStDisabled) {
2650 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002652 // maybe try a FSM reset and then again ... - TODO!!!
2653 } else {
2654 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002655 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002656 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002657 }
2658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002660 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002661 // maybe try a FSM reset and then again ... - TODO!!!
2662 }
2663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002664 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002665 // maybe try a FSM reset and then again ... - TODO!!!
2666 }
2667}
2668
mpagenko80622a52021-02-09 16:53:23 +00002669// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002670func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002671 //in here lockUpgradeFsm is already locked
2672 chUpgradeFsm := make(chan Message, 2048)
2673 var sFsmName = "OnuSwUpgradeFSM"
2674 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002675 if apDevEntry.PDevOmciCC == nil {
2676 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2677 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002678 }
mpagenko15ff4a52021-03-02 10:09:20 +00002679 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002680 sFsmName, chUpgradeFsm)
2681 if dh.pOnuUpradeFsm != nil {
2682 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2683 if pUpgradeStatemachine != nil {
2684 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2685 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2686 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2687 // maybe try a FSM reset and then again ... - TODO!!!
2688 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2689 }
2690 /***** LockStateFSM started */
mpagenko38662d02021-08-11 09:45:19 +00002691 //reset the last stored upgrade states
2692 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_STARTED //already with updated state
2693 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2694 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002695 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2696 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2697 } else {
2698 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2699 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2700 // maybe try a FSM reset and then again ... - TODO!!!
2701 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2702 }
2703 } else {
2704 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2705 // maybe try a FSM reset and then again ... - TODO!!!
2706 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2707 }
2708 } else {
2709 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2710 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2711 }
2712 return nil
2713}
2714
2715// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko38662d02021-08-11 09:45:19 +00002716func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002717 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2718 "device-id": dh.deviceID})
2719 dh.lockUpgradeFsm.Lock()
mpagenko80622a52021-02-09 16:53:23 +00002720 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
mpagenko38662d02021-08-11 09:45:19 +00002721 dh.pLastUpgradeImageState = apImageState
2722 dh.lockUpgradeFsm.Unlock()
2723 //signal upgradeFsm removed using non-blocking channel send
2724 select {
2725 case dh.upgradeFsmChan <- struct{}{}:
2726 default:
2727 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2728 "device-id": dh.deviceID})
2729 }
mpagenko80622a52021-02-09 16:53:23 +00002730}
2731
mpagenko15ff4a52021-03-02 10:09:20 +00002732// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2733func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2734 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2735 if pDevEntry == nil {
2736 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2737 return
2738 }
2739
2740 dh.lockUpgradeFsm.RLock()
2741 defer dh.lockUpgradeFsm.RUnlock()
2742 if dh.pOnuUpradeFsm != nil {
2743 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2744 if pUpgradeStatemachine != nil {
2745 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2746 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002747 upgradeState := pUpgradeStatemachine.Current()
2748 if (upgradeState == upgradeStWaitForCommit) ||
2749 (upgradeState == upgradeStRequestingActivate) {
2750 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002751 // here no need to update the upgrade image state to activated as the state will be immediately be set to committing
mpagenko59498c12021-03-18 14:15:15 +00002752 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002753 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2754 if errImg != nil {
2755 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2756 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002757 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002758 return
2759 }
mpagenko1f8e8822021-06-25 14:10:21 +00002760 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2761 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2762 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2763 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2764 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2765 return
2766 }
2767 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2768 "state": upgradeState, "device-id": dh.deviceID})
2769 } else {
2770 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2771 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2772 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2773 return
2774 }
2775 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2776 "state": upgradeState, "device-id": dh.deviceID})
2777 }
2778 } else {
2779 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2780 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002781 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko1f8e8822021-06-25 14:10:21 +00002782 return
2783 }
mpagenko15ff4a52021-03-02 10:09:20 +00002784 } else {
2785 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2786 log.Fields{"device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002787 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
mpagenko15ff4a52021-03-02 10:09:20 +00002788 return
2789 }
mpagenko183647c2021-06-08 15:25:04 +00002790 } else {
2791 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2792 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2793 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2794 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2795 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2796 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
mpagenko38662d02021-08-11 09:45:19 +00002797 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002798 }
2799 }
mpagenko15ff4a52021-03-02 10:09:20 +00002800 }
2801 }
2802 } else {
2803 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2804 }
2805}
2806
Himani Chawla6d2ae152020-09-02 13:11:20 +05302807//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002808func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002809
2810 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002811 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002812 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002813 kvbackend := &db.Backend{
2814 Client: dh.pOpenOnuAc.kvClient,
2815 StoreType: dh.pOpenOnuAc.KVStoreType,
2816 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002817 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002818 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2819 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002820
mpagenkoaf801632020-07-03 10:00:42 +00002821 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002822}
khenaidoo7d3c5582021-08-11 18:09:44 -04002823func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *of.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302824 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002825
mpagenkodff5dda2020-08-28 11:52:01 +00002826 for _, field := range flow.GetOfbFields(apFlowItem) {
2827 switch field.Type {
2828 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2829 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002831 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2832 }
mpagenko01e726e2020-10-23 09:45:29 +00002833 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002834 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2835 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302836 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002837 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302838 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2839 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002840 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2841 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002842 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2843 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302844 return
mpagenkodff5dda2020-08-28 11:52:01 +00002845 }
2846 }
mpagenko01e726e2020-10-23 09:45:29 +00002847 */
mpagenkodff5dda2020-08-28 11:52:01 +00002848 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2849 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302850 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002851 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302852 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002853 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302854 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002855 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002856 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302857 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002858 }
2859 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2860 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302861 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002863 "PCP": loAddPcp})
2864 }
2865 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2866 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002867 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002868 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2869 }
2870 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2871 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002872 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002873 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2874 }
2875 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2876 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002877 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002878 "IPv4-DST": field.GetIpv4Dst()})
2879 }
2880 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2881 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002882 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002883 "IPv4-SRC": field.GetIpv4Src()})
2884 }
2885 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2886 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002888 "Metadata": field.GetTableMetadata()})
2889 }
2890 /*
2891 default:
2892 {
2893 //all other entires ignored
2894 }
2895 */
2896 }
2897 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302898}
mpagenkodff5dda2020-08-28 11:52:01 +00002899
khenaidoo7d3c5582021-08-11 18:09:44 -04002900func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *of.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002901 for _, action := range flow.GetActions(apFlowItem) {
2902 switch action.Type {
2903 /* not used:
2904 case of.OfpActionType_OFPAT_OUTPUT:
2905 {
mpagenko01e726e2020-10-23 09:45:29 +00002906 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002907 "Output": action.GetOutput()})
2908 }
2909 */
2910 case of.OfpActionType_OFPAT_PUSH_VLAN:
2911 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002912 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002913 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2914 }
2915 case of.OfpActionType_OFPAT_SET_FIELD:
2916 {
2917 pActionSetField := action.GetSetField()
2918 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002919 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002920 "OxcmClass": pActionSetField.Field.OxmClass})
2921 }
2922 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302923 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002924 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302925 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002926 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302927 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002928 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302929 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002930 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002932 "Type": pActionSetField.Field.GetOfbField().Type})
2933 }
2934 }
2935 /*
2936 default:
2937 {
2938 //all other entires ignored
2939 }
2940 */
2941 }
2942 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302943}
2944
2945//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
khenaidoo7d3c5582021-08-11 18:09:44 -04002946func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *onuUniPort,
ozgecanetsia82b91a62021-05-21 18:54:49 +03002947 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302948 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2949 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2950 var loAddPcp, loSetPcp uint8
2951 var loIPProto uint32
2952 /* the TechProfileId is part of the flow Metadata - compare also comment within
2953 * OLT-Adapter:openolt_flowmgr.go
2954 * Metadata 8 bytes:
2955 * Most Significant 2 Bytes = Inner VLAN
2956 * Next 2 Bytes = Tech Profile ID(TPID)
2957 * Least Significant 4 Bytes = Port ID
2958 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2959 * subscriber related flows.
2960 */
2961
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302963 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002964 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302965 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002966 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302967 }
mpagenko551a4d42020-12-08 18:09:20 +00002968 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002969 loCookie := apFlowItem.GetCookie()
2970 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002971 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002972 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302973
dbainbri4d3a0dc2020-12-02 00:33:42 +00002974 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002975 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302976 if loIPProto == 2 {
2977 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2978 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002979 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2980 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302981 return nil
2982 }
mpagenko01e726e2020-10-23 09:45:29 +00002983 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002984 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002985
2986 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002987 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002988 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2989 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2990 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2991 //TODO!!: Use DeviceId within the error response to rwCore
2992 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002993 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002994 }
2995 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002997 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2998 } else {
2999 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3000 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3001 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303002 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003003 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003005 }
mpagenko9a304ea2020-12-16 15:54:01 +00003006
ozgecanetsia82b91a62021-05-21 18:54:49 +03003007 var meter *voltha.OfpMeterConfig
3008 if apFlowMetaData != nil {
3009 meter = apFlowMetaData.Meters[0]
3010 }
mpagenkobc4170a2021-08-17 16:42:10 +00003011 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3012 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3013 // when different rules are requested concurrently for the same uni
3014 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3015 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3016 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3017 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303018 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkobc4170a2021-08-17 16:42:10 +00003019 //SetUniFlowParams() may block on some rule that is suspended-to-add
3020 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003021 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003022 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenkobc4170a2021-08-17 16:42:10 +00003023 dh.lockVlanConfig.RUnlock()
3024 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003025 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003026 }
mpagenkobc4170a2021-08-17 16:42:10 +00003027 dh.lockVlanConfig.RUnlock()
3028 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko7d14de12021-07-27 08:31:56 +00003029 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003030 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko7d14de12021-07-27 08:31:56 +00003031 dh.lockVlanConfig.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003032 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko7d14de12021-07-27 08:31:56 +00003033 return err
mpagenko01e726e2020-10-23 09:45:29 +00003034}
3035
3036//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
khenaidoo7d3c5582021-08-11 18:09:44 -04003037func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *of.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003038 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3039 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3040 //no extra check is done on the rule parameters
3041 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3042 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3043 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3044 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003045 // - 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 +00003046 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003047 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003048
3049 /* TT related temporary workaround - should not be needed anymore
3050 for _, field := range flow.GetOfbFields(apFlowItem) {
3051 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3052 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003053 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003054 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3055 if loIPProto == 2 {
3056 // 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 +00003057 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003058 log.Fields{"device-id": dh.deviceID})
3059 return nil
3060 }
3061 }
3062 } //for all OfbFields
3063 */
3064
mpagenko9a304ea2020-12-16 15:54:01 +00003065 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003066 dh.lockVlanConfig.RLock()
3067 defer dh.lockVlanConfig.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +00003068 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003069 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003070 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003071 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003072 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003073 log.Fields{"device-id": dh.deviceID})
3074 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003075 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003077
mpagenko01e726e2020-10-23 09:45:29 +00003078 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003079}
3080
Himani Chawla26e555c2020-08-31 12:30:20 +05303081// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003082// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko7d14de12021-07-27 08:31:56 +00003083// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003084func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003085 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003086 chVlanFilterFsm := make(chan Message, 2048)
3087
dbainbri4d3a0dc2020-12-02 00:33:42 +00003088 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003089 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003090 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303091 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003092 }
3093
dbainbri4d3a0dc2020-12-02 00:33:42 +00003094 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003095 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003096 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003097 if pVlanFilterFsm != nil {
mpagenko7d14de12021-07-27 08:31:56 +00003098 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3099 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303100 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003101 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3102 if pVlanFilterStatemachine != nil {
3103 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3104 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003105 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303106 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003107 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303108 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003109 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303110 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3111 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003112 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003113 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003114 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303115 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003116 }
3117 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003118 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003119 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303120 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003121 }
3122 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003124 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303125 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003126 }
3127 return nil
3128}
3129
mpagenkofc4f56e2020-11-04 17:17:49 +00003130//VerifyVlanConfigRequest checks on existence of a given uniPort
3131// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003132func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003133 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3134 var pCurrentUniPort *onuUniPort
3135 for _, uniPort := range dh.uniEntityMap {
3136 // only if this port is validated for operState transfer
3137 if uniPort.uniID == uint8(aUniID) {
3138 pCurrentUniPort = uniPort
3139 break //found - end search loop
3140 }
3141 }
3142 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003143 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003144 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3145 return
3146 }
mpagenko551a4d42020-12-08 18:09:20 +00003147 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003148}
3149
mpagenkodff5dda2020-08-28 11:52:01 +00003150//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003151func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003152 //TODO!! verify and start pending flow configuration
3153 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3154 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003155
3156 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303157 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003158 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003159 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3160 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3161 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003162 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3163 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3164 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3165 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3166 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3167 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3168 } else {
3169 /***** UniVlanConfigFsm continued */
3170 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3171 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3172 "UniPort": apUniPort.portNo})
3173 }
3174 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3175 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3176 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3177 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3178 } else {
3179 /***** UniVlanConfigFsm continued */
3180 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3181 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3182 "UniPort": apUniPort.portNo})
3183 }
mpagenkodff5dda2020-08-28 11:52:01 +00003184 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003185 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3186 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003187 "UniPort": apUniPort.portNo})
3188 }
3189 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003190 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3191 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3192 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003193 }
3194 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003195 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003196 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003197 }
mpagenkof1fc3862021-02-16 10:09:52 +00003198 } else {
3199 dh.lockVlanConfig.RUnlock()
3200 }
mpagenkodff5dda2020-08-28 11:52:01 +00003201}
3202
3203//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3204// intention is to provide this method to be called from VlanConfigFsm itself, when resources (and methods!) are cleaned up
dbainbri4d3a0dc2020-12-02 00:33:42 +00003205func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3206 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003207 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3208 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003209 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303210 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003211 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003212}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003213
mpagenkof1fc3862021-02-16 10:09:52 +00003214//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3215func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3216 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3217 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3218 // obviously then parallel processing on the cancel must be avoided
3219 // deadline context to ensure completion of background routines waited for
3220 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3221 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3222 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3223
3224 aPDevEntry.resetKvProcessingErrorIndication()
3225 var wg sync.WaitGroup
3226 wg.Add(1) // for the 1 go routine to finish
3227
3228 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3229 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3230
3231 return aPDevEntry.getKvProcessingErrorIndication()
3232}
3233
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003234//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3235//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003236func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3237 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003238
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003239 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003240 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003241 return nil
3242 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003243 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003244
dbainbri4d3a0dc2020-12-02 00:33:42 +00003245 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003246 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003247 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003248 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3249 }
3250 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3251
mpagenkof1fc3862021-02-16 10:09:52 +00003252 if aWriteToKvStore {
3253 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3254 }
3255 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003256}
3257
dbainbri4d3a0dc2020-12-02 00:33:42 +00003258func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003259 defer cancel() //ensure termination of context (may be pro forma)
3260 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003261 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003262 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003263}
3264
dbainbri4d3a0dc2020-12-02 00:33:42 +00003265func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003266
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003267 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003268 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003269 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
khenaidoo7d3c5582021-08-11 18:09:44 -04003270 if err := dh.updateDeviceReasonInCore(ctx, &ic.DeviceReason{
3271 DeviceId: dh.deviceID,
3272 Reason: deviceReasonMap[deviceReason],
3273 }); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003274 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003275 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003276 return err
3277 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003278 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003279 return nil
3280 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003281 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003282 return nil
3283}
3284
dbainbri4d3a0dc2020-12-02 00:33:42 +00003285func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3286 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003287 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003288 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003289 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3290 }
mpagenkof1fc3862021-02-16 10:09:52 +00003291 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003292}
3293
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003294// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003295// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003296func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3297 dh.lockDevice.RLock()
3298 defer dh.lockDevice.RUnlock()
3299 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3300 return uniPort.entityID, nil
3301 }
3302 return 0, errors.New("error-fetching-uni-port")
3303}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003304
3305// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003306func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3307 var errorsList []error
3308 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 -08003309
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003310 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3311 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3312 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3313
3314 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3315 // successfully.
3316 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3317 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3318 if len(errorsList) > 0 {
3319 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3320 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003321 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003322 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3323 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003324}
3325
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003326func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3327 var err error
3328 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003329 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003330
3331 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3332 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3333 errorsList = append(errorsList, err)
3334 }
3335 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003336 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003337
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003338 return errorsList
3339}
3340
3341func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3342 var err error
3343 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003344 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003345 // Check if group metric related config is updated
3346 for _, v := range pmConfigs.Groups {
3347 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3348 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3349 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3350
3351 if ok && m.frequency != v.GroupFreq {
3352 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3353 errorsList = append(errorsList, err)
3354 }
3355 }
3356 if ok && m.enabled != v.Enabled {
3357 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3358 errorsList = append(errorsList, err)
3359 }
3360 }
3361 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003362 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003363 return errorsList
3364}
3365
3366func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3367 var err error
3368 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003369 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003370 // Check if standalone metric related config is updated
3371 for _, v := range pmConfigs.Metrics {
3372 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003373 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003374 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3375
3376 if ok && m.frequency != v.SampleFreq {
3377 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3378 errorsList = append(errorsList, err)
3379 }
3380 }
3381 if ok && m.enabled != v.Enabled {
3382 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3383 errorsList = append(errorsList, err)
3384 }
3385 }
3386 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003387 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003388 return errorsList
3389}
3390
3391// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003392func (dh *deviceHandler) startCollector(ctx context.Context) {
3393 logger.Debugf(ctx, "startingCollector")
3394
3395 // Start routine to process OMCI GET Responses
3396 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303397 // Create Extended Frame PM ME
3398 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003399 // Initialize the next metric collection time.
3400 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3401 // reset like onu rebooted.
3402 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003403 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003404 for {
3405 select {
3406 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003407 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003408 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003409 // Stop the L2 PM FSM
3410 go func() {
3411 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3412 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3413 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3414 }
3415 } else {
3416 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3417 }
3418 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003419 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3420 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3421 }
3422 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3423 dh.pOnuMetricsMgr.stopTicks <- true
3424 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003425
Girish Gowdrae09a6202021-01-12 18:10:59 -08003426 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003427 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3428 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3429 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3430 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3431 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003432 // Update the next metric collection time.
3433 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003434 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003435 } else {
3436 if dh.pmConfigs.Grouped { // metrics are managed as a group
3437 // parse through the group and standalone metrics to see it is time to collect their metrics
3438 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003439
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003440 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3441 // 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 -08003442 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3443 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003444 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3445 }
3446 }
3447 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3448 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3449 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3450 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3451 }
3452 }
3453 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3454
3455 // parse through the group and update the next metric collection time
3456 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3457 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3458 // 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 -08003459 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3460 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003461 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3462 }
3463 }
3464 // parse through the standalone metrics and update the next metric collection time
3465 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3466 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3467 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3468 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3469 }
3470 }
3471 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3472 } /* else { // metrics are not managed as a group
3473 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3474 } */
3475 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003476 }
3477 }
3478}
kesavandfdf77632021-01-26 23:40:33 -05003479
3480func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3481
3482 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3483 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3484}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003485
Himani Chawla43f95ff2021-06-03 00:24:12 +05303486func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3487 if dh.pOnuMetricsMgr == nil {
3488 return &extension.SingleGetValueResponse{
3489 Response: &extension.GetValueResponse{
3490 Status: extension.GetValueResponse_ERROR,
3491 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3492 },
3493 }
3494 }
3495 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3496 return resp
3497}
3498
mpagenkof1fc3862021-02-16 10:09:52 +00003499func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3500 if pFsm == nil {
3501 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003502 }
mpagenkof1fc3862021-02-16 10:09:52 +00003503 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003504}
3505
mpagenkof1fc3862021-02-16 10:09:52 +00003506func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3507 var pFsm *fsm.FSM
3508 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3509 switch omciFsm {
3510 case cUploadFsm:
3511 {
3512 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3513 }
3514 case cDownloadFsm:
3515 {
3516 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3517 }
3518 case cUniLockFsm:
3519 {
3520 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3521 }
3522 case cUniUnLockFsm:
3523 {
3524 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3525 }
3526 case cL2PmFsm:
3527 {
3528 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3529 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3530 } else {
3531 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003532 }
3533 }
mpagenko80622a52021-02-09 16:53:23 +00003534 case cOnuUpgradeFsm:
3535 {
3536 dh.lockUpgradeFsm.RLock()
3537 defer dh.lockUpgradeFsm.RUnlock()
3538 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3539 }
mpagenkof1fc3862021-02-16 10:09:52 +00003540 default:
3541 {
3542 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3543 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3544 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003545 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003546 }
mpagenkof1fc3862021-02-16 10:09:52 +00003547 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003548}
3549
mpagenkof1fc3862021-02-16 10:09:52 +00003550func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3551 for _, v := range dh.pOnuTP.pAniConfigFsm {
3552 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003553 return false
3554 }
3555 }
3556 return true
3557}
3558
mpagenkof1fc3862021-02-16 10:09:52 +00003559func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3560 dh.lockVlanConfig.RLock()
3561 defer dh.lockVlanConfig.RUnlock()
3562 for _, v := range dh.UniVlanConfigFsmMap {
3563 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3564 return false
3565 }
3566 }
3567 return true //FSM not active - so there is no activity on omci
3568}
3569
3570func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3571 dh.lockVlanConfig.RLock()
3572 defer dh.lockVlanConfig.RUnlock()
3573 for _, v := range dh.UniVlanConfigFsmMap {
3574 if v.pAdaptFsm.pFsm != nil {
3575 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3576 return true //there is at least one VLAN FSM with some active configuration
3577 }
3578 }
3579 }
3580 return false //there is no VLAN FSM with some active configuration
3581}
3582
3583func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3584 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3585 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3586 return false
3587 }
3588 }
3589 // a further check is done to identify, if at least some data traffic related configuration exists
3590 // 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])
3591 return dh.checkUserServiceExists(ctx)
3592}
3593
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003594func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3595 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3596 if err := dh.resetFsms(ctx, false); err != nil {
3597 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3598 // TODO: fatal error reset ONU, delete deviceHandler!
3599 return
3600 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003601 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003602 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003603}
3604
3605func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3606 dh.mutexCollectorFlag.Lock()
3607 dh.collectorIsRunning = flagValue
3608 dh.mutexCollectorFlag.Unlock()
3609}
3610
3611func (dh *deviceHandler) getCollectorIsRunning() bool {
3612 dh.mutexCollectorFlag.RLock()
3613 flagValue := dh.collectorIsRunning
3614 dh.mutexCollectorFlag.RUnlock()
3615 return flagValue
3616}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303617
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303618func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3619 dh.mutextAlarmManagerFlag.Lock()
3620 dh.alarmManagerIsRunning = flagValue
3621 dh.mutextAlarmManagerFlag.Unlock()
3622}
3623
Himani Chawla1472c682021-03-17 17:11:14 +05303624func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303625 dh.mutextAlarmManagerFlag.RLock()
3626 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303627 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303628 dh.mutextAlarmManagerFlag.RUnlock()
3629 return flagValue
3630}
3631
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303632func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3633 logger.Debugf(ctx, "startingAlarmManager")
3634
3635 // Start routine to process OMCI GET Responses
3636 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303637 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303638 if stop := <-dh.stopAlarmManager; stop {
3639 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303640 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303641 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303642 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3643 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3644 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303645 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303646 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303647 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3648 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303649 }
3650}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003651
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003652func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003653 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003654
Maninder7961d722021-06-16 22:10:28 +05303655 connectStatus := voltha.ConnectStatus_UNREACHABLE
3656 operState := voltha.OperStatus_UNKNOWN
3657
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003658 if !dh.isReconciling() {
3659 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003660 logger.Debugw(ctx, "wait for channel signal or timeout",
3661 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003662 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003663 case success := <-dh.chReconcilingFinished:
3664 if success {
Maninderb5187552021-03-23 22:23:42 +05303665 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3666 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3667 log.Fields{"device-id": dh.deviceID})
3668 } else {
Maninderb5187552021-03-23 22:23:42 +05303669 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3670 connectStatus = voltha.ConnectStatus_REACHABLE
3671 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3672 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3673 operState = voltha.OperStatus_ACTIVE
3674 } else {
3675 operState = voltha.OperStatus_ACTIVATING
3676 }
3677 }
3678 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3679 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3680 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3681 operState = voltha.OperStatus_DISCOVERED
3682 }
3683
3684 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303685 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003686 logger.Debugw(ctx, "reconciling has been finished in time",
3687 log.Fields{"device-id": dh.deviceID})
khenaidoo7d3c5582021-08-11 18:09:44 -04003688 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
3689 DeviceId: dh.deviceID,
3690 ConnStatus: connectStatus,
3691 OperStatus: operState,
3692 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303693 logger.Errorw(ctx, "unable to update device state to core",
3694 log.Fields{"device-id": dh.deviceID, "Err": err})
3695 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003696 } else {
Maninderb5187552021-03-23 22:23:42 +05303697 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003698 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303699
3700 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3701 logger.Errorw(ctx, "No valid OnuDevice",
3702 log.Fields{"device-id": dh.deviceID})
3703 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3704 connectStatus = voltha.ConnectStatus_REACHABLE
3705 }
3706
3707 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003708 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003709 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003710 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3711 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303712
3713 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3714 logger.Errorw(ctx, "No valid OnuDevice",
3715 log.Fields{"device-id": dh.deviceID})
3716 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3717 connectStatus = voltha.ConnectStatus_REACHABLE
3718 }
3719
3720 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3721
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003722 }
3723 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003724 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003725 dh.mutexReconcilingFlag.Unlock()
3726 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003727 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003728 dh.mutexReconcilingFlag.Lock()
3729 if skipOnuConfig {
3730 dh.reconciling = cSkipOnuConfigReconciling
3731 } else {
3732 dh.reconciling = cOnuConfigReconciling
3733 }
3734 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003735}
3736
Girish Gowdra50e56422021-06-01 16:46:04 -07003737func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3738 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003739 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003740 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003741 } else {
3742 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3743 }
3744}
3745
3746func (dh *deviceHandler) isReconciling() bool {
3747 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003748 defer dh.mutexReconcilingFlag.RUnlock()
3749 return dh.reconciling != cNoReconciling
3750}
3751
3752func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3753 dh.mutexReconcilingFlag.RLock()
3754 defer dh.mutexReconcilingFlag.RUnlock()
3755 return dh.reconciling == cSkipOnuConfigReconciling
3756}
3757
3758func (dh *deviceHandler) setDeviceReason(value uint8) {
3759 dh.mutexDeviceReason.Lock()
3760 dh.deviceReason = value
3761 dh.mutexDeviceReason.Unlock()
3762}
3763
3764func (dh *deviceHandler) getDeviceReason() uint8 {
3765 dh.mutexDeviceReason.RLock()
3766 value := dh.deviceReason
3767 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003768 return value
3769}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003770
3771func (dh *deviceHandler) getDeviceReasonString() string {
3772 return deviceReasonMap[dh.getDeviceReason()]
3773}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003774
3775func (dh *deviceHandler) setReconcilingFlows(value bool) {
3776 dh.mutexReconcilingFlowsFlag.Lock()
3777 dh.reconcilingFlows = value
3778 dh.mutexReconcilingFlowsFlag.Unlock()
3779}
3780
3781func (dh *deviceHandler) isReconcilingFlows() bool {
3782 dh.mutexReconcilingFlowsFlag.RLock()
3783 value := dh.reconcilingFlows
3784 dh.mutexReconcilingFlowsFlag.RUnlock()
3785 return value
3786}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003787
3788func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3789 dh.mutexReadyForOmciConfig.Lock()
3790 dh.readyForOmciConfig = flagValue
3791 dh.mutexReadyForOmciConfig.Unlock()
3792}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003793func (dh *deviceHandler) isReadyForOmciConfig() bool {
3794 dh.mutexReadyForOmciConfig.RLock()
3795 flagValue := dh.readyForOmciConfig
3796 dh.mutexReadyForOmciConfig.RUnlock()
3797 return flagValue
3798}
Maninder7961d722021-06-16 22:10:28 +05303799
3800func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3801 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3802 logger.Errorw(ctx, "unable to update device reason to core",
3803 log.Fields{"device-id": dh.deviceID, "Err": err})
3804 }
3805
3806 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
khenaidoo7d3c5582021-08-11 18:09:44 -04003807 if err := dh.updateDeviceStateInCore(ctx, &ic.DeviceStateFilter{
3808 DeviceId: dh.deviceID,
3809 ConnStatus: connectStatus,
3810 OperStatus: voltha.OperStatus_RECONCILING_FAILED,
3811 }); err != nil {
Maninder7961d722021-06-16 22:10:28 +05303812 logger.Errorw(ctx, "unable to update device state to core",
3813 log.Fields{"device-id": dh.deviceID, "Err": err})
3814 }
3815}
khenaidoo7d3c5582021-08-11 18:09:44 -04003816
3817/*
3818Helper functions to communicate with Core
3819*/
3820
3821func (dh *deviceHandler) getDeviceFromCore(ctx context.Context, deviceID string) (*voltha.Device, error) {
3822 cClient, err := dh.coreClient.GetCoreServiceClient()
3823 if err != nil || cClient == nil {
3824 return nil, err
3825 }
3826 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3827 defer cancel()
3828 logger.Debugw(subCtx, "get-device-from-core", log.Fields{"device-id": deviceID})
3829 return cClient.GetDevice(subCtx, &vc.ID{Id: deviceID})
3830}
3831
3832func (dh *deviceHandler) updateDeviceStateInCore(ctx context.Context, deviceStateFilter *ic.DeviceStateFilter) error {
3833 cClient, err := dh.coreClient.GetCoreServiceClient()
3834 if err != nil || cClient == nil {
3835 return err
3836 }
3837 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3838 defer cancel()
3839 _, err = cClient.DeviceStateUpdate(subCtx, deviceStateFilter)
3840 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-state": deviceStateFilter, "error": err})
3841 return err
3842}
3843
3844func (dh *deviceHandler) updatePMConfigInCore(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3845 cClient, err := dh.coreClient.GetCoreServiceClient()
3846 if err != nil || cClient == nil {
3847 return err
3848 }
3849 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3850 defer cancel()
3851 _, err = cClient.DevicePMConfigUpdate(subCtx, pmConfigs)
3852 logger.Debugw(subCtx, "pmconfig-updated-in-core", log.Fields{"pm-configs": pmConfigs, "error": err})
3853 return err
3854}
3855
3856func (dh *deviceHandler) updateDeviceInCore(ctx context.Context, device *voltha.Device) error {
3857 cClient, err := dh.coreClient.GetCoreServiceClient()
3858 if err != nil || cClient == nil {
3859 return err
3860 }
3861 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3862 defer cancel()
3863 _, err = cClient.DeviceUpdate(subCtx, device)
3864 logger.Debugw(subCtx, "device-updated-in-core", log.Fields{"device-id": device.Id, "error": err})
3865 return err
3866}
3867
3868func (dh *deviceHandler) createPortInCore(ctx context.Context, port *voltha.Port) error {
3869 cClient, err := dh.coreClient.GetCoreServiceClient()
3870 if err != nil || cClient == nil {
3871 return err
3872 }
3873 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3874 defer cancel()
3875 _, err = cClient.PortCreated(subCtx, port)
3876 logger.Debugw(subCtx, "port-created-in-core", log.Fields{"port": port, "error": err})
3877 return err
3878}
3879
3880func (dh *deviceHandler) updatePortStateInCore(ctx context.Context, portState *ic.PortState) error {
3881 cClient, err := dh.coreClient.GetCoreServiceClient()
3882 if err != nil || cClient == nil {
3883 return err
3884 }
3885 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3886 defer cancel()
3887 _, err = cClient.PortStateUpdate(subCtx, portState)
3888 logger.Debugw(subCtx, "port-state-updated-in-core", log.Fields{"port-state": portState, "error": err})
3889 return err
3890}
3891
3892func (dh *deviceHandler) updateDeviceReasonInCore(ctx context.Context, reason *ic.DeviceReason) error {
3893 cClient, err := dh.coreClient.GetCoreServiceClient()
3894 if err != nil || cClient == nil {
3895 return err
3896 }
3897 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.RPCTimeout)
3898 defer cancel()
3899 _, err = cClient.DeviceReasonUpdate(subCtx, reason)
3900 logger.Debugw(subCtx, "device-reason-updated-in-core", log.Fields{"reason": reason, "error": err})
3901 return err
3902}
3903
3904/*
3905Helper functions to communicate with parent adapter
3906*/
3907
3908func (dh *deviceHandler) getTechProfileInstanceFromParentAdapter(ctx context.Context, parentEndpoint string,
3909 request *ic.TechProfileInstanceRequestMessage) (*ic.TechProfileDownloadMessage, error) {
3910 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
3911 if err != nil || pgClient == nil {
3912 return nil, err
3913 }
3914 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
3915 defer cancel()
3916 logger.Debugw(subCtx, "get-tech-profile-instance", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
3917 return pgClient.GetTechProfileInstance(subCtx, request)
3918}
3919
3920func (dh *deviceHandler) sendOMCIRequest(ctx context.Context, parentEndpoint string, request *ic.OmciMessage) error {
3921 pgClient, err := dh.pOpenOnuAc.getParentAdapterServiceClient(parentEndpoint)
3922 if err != nil || pgClient == nil {
3923 return err
3924 }
3925 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), dh.config.MaxTimeoutInterAdapterComm)
3926 defer cancel()
3927 logger.Debugw(subCtx, "send-omci-request", log.Fields{"request": request, "parent-endpoint": parentEndpoint})
3928 _, err = pgClient.ProxyOmciRequest(subCtx, request)
3929 if err != nil {
3930 logger.Errorw(ctx, "omci-failure", log.Fields{"request": request, "error": err, "request-parent": request.ParentDeviceId, "request-child": request.ChildDeviceId, "request-proxy": request.ProxyAddress})
3931 }
3932 return err
3933}