blob: e5444d4e2a91a65e7ee320c45520b1fb5ec2f39f [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"
Girish Gowdra50e56422021-06-01 16:46:04 -070024 "github.com/opencord/voltha-protos/v4/go/tech_profile"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000025 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000026 "sync"
27 "time"
28
29 "github.com/gogo/protobuf/proto"
30 "github.com/golang/protobuf/ptypes"
31 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000032 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070033 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
34 "github.com/opencord/voltha-lib-go/v5/pkg/db"
35 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
36 flow "github.com/opencord/voltha-lib-go/v5/pkg/flows"
37 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000038 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050039 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000040 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
41 "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 oop "github.com/opencord/voltha-protos/v4/go/openolt"
45 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000046)
47
48/*
49// Constants for number of retries and for timeout
50const (
51 MaxRetry = 10
52 MaxTimeOutInMs = 500
53)
54*/
55
mpagenko1cc3cb42020-07-27 15:24:38 +000056const (
57 // events of Device FSM
58 devEvDeviceInit = "devEvDeviceInit"
59 devEvGrpcConnected = "devEvGrpcConnected"
60 devEvGrpcDisconnected = "devEvGrpcDisconnected"
61 devEvDeviceUpInd = "devEvDeviceUpInd"
62 devEvDeviceDownInd = "devEvDeviceDownInd"
63)
64const (
65 // states of Device FSM
66 devStNull = "devStNull"
67 devStDown = "devStDown"
68 devStInit = "devStInit"
69 devStConnected = "devStConnected"
70 devStUp = "devStUp"
71)
72
Holger Hildebrandt24d51952020-05-04 14:03:42 +000073//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
74const (
Himani Chawla4d908332020-08-31 12:30:20 +053075 pon = voltha.EventSubCategory_PON
76 //olt = voltha.EventSubCategory_OLT
77 //ont = voltha.EventSubCategory_ONT
78 //onu = voltha.EventSubCategory_ONU
79 //nni = voltha.EventSubCategory_NNI
80 //service = voltha.EventCategory_SERVICE
81 //security = voltha.EventCategory_SECURITY
82 equipment = voltha.EventCategory_EQUIPMENT
83 //processing = voltha.EventCategory_PROCESSING
84 //environment = voltha.EventCategory_ENVIRONMENT
85 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000086)
87
88const (
89 cEventObjectType = "ONU"
90)
91const (
92 cOnuActivatedEvent = "ONU_ACTIVATED"
93)
94
Holger Hildebrandt10d98192021-01-27 15:29:31 +000095type usedOmciConfigFsms int
96
97const (
98 cUploadFsm usedOmciConfigFsms = iota
99 cDownloadFsm
100 cUniLockFsm
101 cUniUnLockFsm
102 cAniConfigFsm
103 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800104 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000105 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000106)
107
mpagenkof1fc3862021-02-16 10:09:52 +0000108type omciIdleCheckStruct struct {
109 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
110 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000111}
112
mpagenkof1fc3862021-02-16 10:09:52 +0000113var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
114 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
115 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
116 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
118 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
119 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
120 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000121 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000122}
123
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000124const (
125 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000126 drUnset = 0
127 drActivatingOnu = 1
128 drStartingOpenomci = 2
129 drDiscoveryMibsyncComplete = 3
130 drInitialMibDownloaded = 4
131 drTechProfileConfigDownloadSuccess = 5
132 drOmciFlowsPushed = 6
133 drOmciAdminLock = 7
134 drOnuReenabled = 8
135 drStoppingOpenomci = 9
136 drRebooting = 10
137 drOmciFlowsDeleted = 11
138 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530139 drReconcileFailed = 13
140 drReconcileMaxTimeout = 14
141 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700142 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000143)
144
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000145var deviceReasonMap = map[uint8]string{
146 drUnset: "unset",
147 drActivatingOnu: "activating-onu",
148 drStartingOpenomci: "starting-openomci",
149 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
150 drInitialMibDownloaded: "initial-mib-downloaded",
151 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700152 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000153 drOmciFlowsPushed: "omci-flows-pushed",
154 drOmciAdminLock: "omci-admin-lock",
155 drOnuReenabled: "onu-reenabled",
156 drStoppingOpenomci: "stopping-openomci",
157 drRebooting: "rebooting",
158 drOmciFlowsDeleted: "omci-flows-deleted",
159 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530160 drReconcileFailed: "reconcile-failed",
161 drReconcileMaxTimeout: "reconcile-max-timeout",
162 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000163}
164
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000165const (
166 cNoReconciling = iota
167 cOnuConfigReconciling
168 cSkipOnuConfigReconciling
169)
170
Himani Chawla6d2ae152020-09-02 13:11:20 +0530171//deviceHandler will interact with the ONU ? device.
172type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173 deviceID string
174 DeviceType string
175 adminState string
176 device *voltha.Device
177 logicalDeviceID string
178 ProxyAddressID string
179 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530180 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000181 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000182
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000183 coreProxy adapterif.CoreProxy
184 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530185 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000186
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800187 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800188
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000189 pOpenOnuAc *OpenONUAC
190 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530191 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000192 deviceEntrySet chan bool //channel for DeviceEntry set event
193 pOnuOmciDevice *OnuDeviceEntry
194 pOnuTP *onuUniTechProf
195 pOnuMetricsMgr *onuMetricsManager
196 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700197 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000198 exitChannel chan int
199 lockDevice sync.RWMutex
200 pOnuIndication *oop.OnuIndication
201 deviceReason uint8
202 mutexDeviceReason sync.RWMutex
203 pLockStateFsm *lockStateFsm
204 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000205
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000206 //flowMgr *OpenOltFlowMgr
207 //eventMgr *OpenOltEventMgr
208 //resourceMgr *rsrcMgr.OpenOltResourceMgr
209
210 //discOnus sync.Map
211 //onus sync.Map
212 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000213 collectorIsRunning bool
214 mutexCollectorFlag sync.RWMutex
215 stopCollector chan bool
216 alarmManagerIsRunning bool
217 mutextAlarmManagerFlag sync.RWMutex
218 stopAlarmManager chan bool
219 stopHeartbeatCheck chan bool
220 uniEntityMap map[uint32]*onuUniPort
221 mutexKvStoreContext sync.Mutex
222 lockVlanConfig sync.RWMutex
223 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
224 lockUpgradeFsm sync.RWMutex
225 pOnuUpradeFsm *OnuUpgradeFsm
226 reconciling uint8
227 mutexReconcilingFlag sync.RWMutex
228 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000229 reconcilingFlows bool
230 mutexReconcilingFlowsFlag sync.RWMutex
231 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000232 mutexReadyForOmciConfig sync.RWMutex
233 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000234 deletionInProgress bool
235 mutexDeletionInProgressFlag sync.RWMutex
mpagenkoaa3afe92021-05-21 16:20:58 +0000236 upgradeSuccess bool
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000237}
238
Himani Chawla6d2ae152020-09-02 13:11:20 +0530239//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530240func newDeviceHandler(ctx context.Context, cp adapterif.CoreProxy, ap adapterif.AdapterProxy, ep eventif.EventProxy, device *voltha.Device, adapter *OpenONUAC) *deviceHandler {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530241 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 dh.coreProxy = cp
243 dh.AdapterProxy = ap
244 dh.EventProxy = ep
245 cloned := (proto.Clone(device)).(*voltha.Device)
246 dh.deviceID = cloned.Id
247 dh.DeviceType = cloned.Type
248 dh.adminState = "up"
249 dh.device = cloned
250 dh.pOpenOnuAc = adapter
251 dh.exitChannel = make(chan int, 1)
252 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000253 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000254 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000255 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530256 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530257 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000258 dh.stopHeartbeatCheck = make(chan bool, 2)
259 //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 +0000260 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530261 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000262 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000263 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000264 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000265 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000266 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000267 dh.reconcilingFlows = false
268 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000269 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000270 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000271
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800272 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
273 dh.pmConfigs = cloned.PmConfigs
274 } /* else {
275 // will be populated when onu_metrics_mananger is initialized.
276 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800277
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 // Device related state machine
279 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000280 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000282 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
283 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
284 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
285 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
286 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000287 },
288 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000289 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
290 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
291 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
292 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
293 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
294 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
295 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
296 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297 },
298 )
mpagenkoaf801632020-07-03 10:00:42 +0000299
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300 return &dh
301}
302
Himani Chawla6d2ae152020-09-02 13:11:20 +0530303// start save the device to the data model
304func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000305 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000307 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308}
309
Himani Chawla4d908332020-08-31 12:30:20 +0530310/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000311// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530312func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313 logger.Debug("stopping-device-handler")
314 dh.exitChannel <- 1
315}
Himani Chawla4d908332020-08-31 12:30:20 +0530316*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000317
318// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530319// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000320
Girish Gowdrae0140f02021-02-02 16:55:09 -0800321//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530322func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000324
dbainbri4d3a0dc2020-12-02 00:33:42 +0000325 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000326 if dh.pDeviceStateFsm.Is(devStNull) {
327 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
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())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800331 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
332 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800333 // Now, set the initial PM configuration for that device
334 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
335 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
336 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800337 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000338 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000340 }
341
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000342}
343
mpagenko057889c2021-01-21 16:51:58 +0000344func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530345 msgBody := msg.GetBody()
346 omciMsg := &ic.InterAdapterOmciMessage{}
347 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 "device-id": dh.deviceID, "error": err})
350 return err
351 }
352
mpagenko80622a52021-02-09 16:53:23 +0000353 /* 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 +0530354 //assuming omci message content is hex coded!
355 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000358 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000359 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530360 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000361 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000362 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000363 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Debugw(ctx, "omciCC not ready to receive omci messages - incoming omci message ignored", log.Fields{"rxMsg": omciMsg.Message})
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530368}
369
Himani Chawla6d2ae152020-09-02 13:11:20 +0530370func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000371 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530372 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000373
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000375
dbainbri4d3a0dc2020-12-02 00:33:42 +0000376 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000377 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000379 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
380 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 if dh.pOnuTP == nil {
382 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000383 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530384 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530386 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000387 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000389 "device-state": dh.getDeviceReasonString()})
390 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530391 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000392 //previous state test here was just this one, now extended for more states to reject the SetRequest:
393 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
394 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530395
396 msgBody := msg.GetBody()
397 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
398 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000399 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530400 "device-id": dh.deviceID, "error": err})
401 return err
402 }
403
404 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000405 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
406 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530407 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000408 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409
410 if techProfMsg.UniId > 255 {
411 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
412 techProfMsg.UniId, dh.deviceID))
413 }
414 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700415 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800416 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700417 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800418 return err
419 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700420 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000421
Girish Gowdra50e56422021-06-01 16:46:04 -0700422 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530423
Girish Gowdra50e56422021-06-01 16:46:04 -0700424 switch tpInst := techProfMsg.TechTpInstance.(type) {
425 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
426 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
427 // if there has been some change for some uni TechProfilePath
428 //in order to allow concurrent calls to other dh instances we do not wait for execution here
429 //but doing so we can not indicate problems to the caller (who does what with that then?)
430 //by now we just assume straightforward successful execution
431 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
432 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530433
Girish Gowdra50e56422021-06-01 16:46:04 -0700434 // deadline context to ensure completion of background routines waited for
435 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
436 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
437 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000438
Girish Gowdra50e56422021-06-01 16:46:04 -0700439 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
440
441 var wg sync.WaitGroup
442 wg.Add(1) // for the 1 go routine to finish
443 // attention: deadline completion check and wg.Done is to be done in both routines
444 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
445 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
446 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
447 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
448 return tpErr
449 }
450 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
451 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
452 pDevEntry.resetKvProcessingErrorIndication()
453 wg.Add(1) // for the 1 go routine to finish
454 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
455 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
456 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
457 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
458 return kvErr
459 }
460 return nil
461 default:
462 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
463 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700464 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530465 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000466 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700467 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 +0530468 return nil
469}
470
Himani Chawla6d2ae152020-09-02 13:11:20 +0530471func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000472 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 msg *ic.InterAdapterMessage) error {
474
dbainbri4d3a0dc2020-12-02 00:33:42 +0000475 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000476
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000478 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000479 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000480 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
481 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530482 if dh.pOnuTP == nil {
483 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000484 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530485 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530487 }
488
489 msgBody := msg.GetBody()
490 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
491 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530493 "device-id": dh.deviceID, "error": err})
494 return err
495 }
496
497 //compare TECH_PROFILE_DOWNLOAD_REQUEST
498 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000499 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530500
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501 if delGemPortMsg.UniId > 255 {
502 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
503 delGemPortMsg.UniId, dh.deviceID))
504 }
505 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700506 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800507 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700508 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 -0800509 return err
510 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530511
mpagenkofc4f56e2020-11-04 17:17:49 +0000512 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513
mpagenkofc4f56e2020-11-04 17:17:49 +0000514 // deadline context to ensure completion of background routines waited for
515 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
516 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517
Girish Gowdra041dcb32020-11-16 16:54:30 -0800518 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000519
mpagenkofc4f56e2020-11-04 17:17:49 +0000520 var wg sync.WaitGroup
521 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700522 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpInstancePath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000523 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000525
Girish Gowdra041dcb32020-11-16 16:54:30 -0800526 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530527}
528
Himani Chawla6d2ae152020-09-02 13:11:20 +0530529func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000530 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530531 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000532
dbainbri4d3a0dc2020-12-02 00:33:42 +0000533 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000534
dbainbri4d3a0dc2020-12-02 00:33:42 +0000535 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000536 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000537 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000538 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
539 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530540 if dh.pOnuTP == nil {
541 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000542 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530543 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000544 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530545 }
546
547 msgBody := msg.GetBody()
548 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
549 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530551 "device-id": dh.deviceID, "error": err})
552 return err
553 }
554
555 //compare TECH_PROFILE_DOWNLOAD_REQUEST
556 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000557 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000558
559 if delTcontMsg.UniId > 255 {
560 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
561 delTcontMsg.UniId, dh.deviceID))
562 }
563 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700564 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800565 tpID, err := GetTpIDFromTpPath(tpPath)
566 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000567 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800568 return err
569 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000570
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700572 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530573 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530574 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530575 dctx, cancel := context.WithDeadline(context.Background(), deadline)
576
Girish Gowdra041dcb32020-11-16 16:54:30 -0800577 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000578 pDevEntry.resetKvProcessingErrorIndication()
579
Himani Chawla26e555c2020-08-31 12:30:20 +0530580 var wg sync.WaitGroup
581 wg.Add(2) // for the 2 go routines to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700582 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpInstancePath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530583 cResourceTcont, delTcontMsg.AllocId, &wg)
584 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000585 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
586 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000587
Girish Gowdra041dcb32020-11-16 16:54:30 -0800588 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530589 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530590 return nil
591}
592
Himani Chawla6d2ae152020-09-02 13:11:20 +0530593//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
595// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000597 msgID := msg.Header.Id
598 msgType := msg.Header.Type
599 fromTopic := msg.Header.FromTopic
600 toTopic := msg.Header.ToTopic
601 toDeviceID := msg.Header.ToDeviceId
602 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000604 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
605
606 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000607 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000608 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
609 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000610 {
mpagenko057889c2021-01-21 16:51:58 +0000611 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000612 }
mpagenkoaf801632020-07-03 10:00:42 +0000613 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
614 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000615 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000616 }
617 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
618 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000619 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000620
mpagenkoaf801632020-07-03 10:00:42 +0000621 }
622 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
623 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000624 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000625 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000626 default:
627 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000628 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000629 "msgType": msg.Header.Type, "device-id": dh.deviceID})
630 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000631 }
632 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000633}
634
mpagenkodff5dda2020-08-28 11:52:01 +0000635//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
637 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000638 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000640
mpagenko01e726e2020-10-23 09:45:29 +0000641 var retError error = nil
642 //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 +0000643 if apOfFlowChanges.ToRemove != nil {
644 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000645 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000647 "device-id": dh.deviceID})
648 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000649 continue
650 }
651 flowInPort := flow.GetInPort(flowItem)
652 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000653 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 +0000654 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
655 continue
656 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000657 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000658 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000660 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000661 continue
662 } else {
663 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530664 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000665 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
666 loUniPort = uniPort
667 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000669 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
670 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
671 flowInPort, dh.deviceID)
672 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000673 }
674 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000676 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000677 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000679 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000680 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000681 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000682 log.Fields{"device-id": dh.deviceID, "error": err})
683 retError = err
684 continue
685 //return err
686 } else { // if last setting succeeds, overwrite possibly previously set error
687 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000688 }
689 }
690 }
691 }
mpagenko01e726e2020-10-23 09:45:29 +0000692 if apOfFlowChanges.ToAdd != nil {
693 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
694 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": dh.deviceID})
697 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
698 continue
699 }
700 flowInPort := flow.GetInPort(flowItem)
701 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000702 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 +0000703 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
704 continue
705 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
706 } else if flowInPort == dh.ponPortNumber {
707 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000709 "device-id": dh.deviceID, "inPort": flowInPort})
710 continue
711 } else {
712 // this is the relevant upstream flow
713 var loUniPort *onuUniPort
714 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
715 loUniPort = uniPort
716 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000717 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000718 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
719 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
720 flowInPort, dh.deviceID)
721 continue
722 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
723 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000724 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
725 // if not, we just throw some error here to have an indication about that, if we really need to support that
726 // then we would need to create some means to activate the internal stored flows
727 // after the device gets active automatically (and still with its dependency to the TechProfile)
728 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
729 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000730 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000731 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000732 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 return fmt.Errorf("improper device state on device %s", dh.deviceID)
734 }
735
mpagenko01e726e2020-10-23 09:45:29 +0000736 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000737 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000738 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
739 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000740 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000741 //try next flow after processing error
742 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000744 log.Fields{"device-id": dh.deviceID, "error": err})
745 retError = err
746 continue
747 //return err
748 } else { // if last setting succeeds, overwrite possibly previously set error
749 retError = nil
750 }
751 }
752 }
753 }
754 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000755}
756
Himani Chawla6d2ae152020-09-02 13:11:20 +0530757//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000758//following are the expected device states after this activity:
759//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
760// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000761func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
762 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000763
mpagenko900ee4b2020-10-12 11:56:34 +0000764 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000765 //note that disableDevice sequences in some 'ONU active' state may yield also
766 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000767 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000768 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000769 //disable-device shall be just a UNi/ONU-G related admin state setting
770 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000771
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000772 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000773 // disable UNI ports/ONU
774 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
775 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000776 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000777 } else { //LockStateFSM already init
778 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000779 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000780 }
781 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000783 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000785 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
786 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000788 }
mpagenko01e726e2020-10-23 09:45:29 +0000789 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000790
791 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000793 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300794 }
795}
796
Himani Chawla6d2ae152020-09-02 13:11:20 +0530797//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
799 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000800
mpagenkoaa3afe92021-05-21 16:20:58 +0000801 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000802 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
803 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
804 // for real ONU's that should have nearly no influence
805 // Note that for real ONU's there is anyway a problematic situation with following sequence:
806 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
807 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
808 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000809 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000810
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000811 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000812 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000813 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000815 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000816 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000818 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300819}
820
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
822 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000823
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 return
828 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000829 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000830 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000831 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000832 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000834 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700835 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000836 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000837 }
Himani Chawla4d908332020-08-31 12:30:20 +0530838 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000839 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000840 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
841 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
842 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
843 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000844 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000845 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000846}
847
dbainbri4d3a0dc2020-12-02 00:33:42 +0000848func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
849 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000850
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000852 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000853 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000854 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700855 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000856 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000857 return
858 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000859 dh.pOnuTP.lockTpProcMutex()
860 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000861 pDevEntry.mutexPersOnuConfig.RLock()
862 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000863
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000865 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000866 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000867 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700868 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000869 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000870 return
871 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000872 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700873 techProfsFound := false
874 techProfInstLoadFailed := false
875outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000876 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000877 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
878 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000879 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000880 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000881 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000882 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700883 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800884 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700885 // Request the TpInstance again from the openolt adapter in case of reconcile
886 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
887 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
888 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
889 dh.parentID, dh.ProxyAddressID)
890 if err != nil || iaTechTpInst == nil {
891 logger.Errorw(ctx, "error fetching tp instance",
892 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
893 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
894 break outerLoop
895 }
896 var tpInst tech_profile.TechProfileInstance
897 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
898 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
899 tpInst = *techTpInst.TpInstance
900 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
901
902 default: // do not support epon or other tech
903 logger.Errorw(ctx, "unsupported-tech", log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
904 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
905 break outerLoop
906 }
907
Girish Gowdra041dcb32020-11-16 16:54:30 -0800908 // deadline context to ensure completion of background routines waited for
909 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
910 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000911 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000912
Girish Gowdra041dcb32020-11-16 16:54:30 -0800913 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
914 var wg sync.WaitGroup
915 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700916 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000917 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800918 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000919 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700920 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
921 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800922 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000923 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000924 if len(uniData.PersFlowParams) != 0 {
925 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000926 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000927 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000928 if !techProfsFound {
929 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
930 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000931 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700932 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000933 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000934 return
935 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700936 if techProfInstLoadFailed {
937 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
938 dh.stopReconciling(ctx, false)
939 return
940 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000941 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
942 }
943 if !flowsFound {
944 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
945 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000946 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700947 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000948 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000949 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950}
951
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
953 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000954
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000957 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000958 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700959 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000960 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000961 return
962 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000963 pDevEntry.mutexPersOnuConfig.RLock()
964 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000965
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000966 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000967 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000968 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000969 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700970 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000971 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000972 return
973 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000975 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000976 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
977 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000978 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000979 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000980 continue
981 }
982 if len(uniData.PersTpPathMap) == 0 {
983 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
984 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000985 // It doesn't make sense to configure any flows if no TPs are available
986 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000987 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000988 var uniPort *onuUniPort
989 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000990 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000991 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000992 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
993 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000994 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700995 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000996 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997 return
998 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000999 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001000 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001001 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001002 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001003 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001004 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001005 // If this is the last flow for the device we need to announce it the waiting
1006 // chReconcilingFlowsFinished channel
1007 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1008 lastFlowToReconcile = true
1009 }
mpagenko01e726e2020-10-23 09:45:29 +00001010 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +00001011 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001012 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001014 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001015 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001017 }
mpagenkof1fc3862021-02-16 10:09:52 +00001018 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001019 } else {
mpagenkof1fc3862021-02-16 10:09:52 +00001020 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001022 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001023 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001025 }
1026 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001027 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001028 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001029 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
1030 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1031 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001032 // this can't be used as global finished reconciling flag because
1033 // assumes is getting called before the state machines for the last flow is completed,
1034 // while this is not guaranteed.
1035 //dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001036 }
1037 if !flowsFound {
1038 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1039 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001040 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001041 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001042 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001043 return
1044 }
1045 if dh.isSkipOnuConfigReconciling() {
1046 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 }
1048}
1049
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001050func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1051 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001052 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001053}
1054
dbainbri4d3a0dc2020-12-02 00:33:42 +00001055func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1056 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001057
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001059 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001060 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001061 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001062 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001063 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001064
1065 // deadline context to ensure completion of background routines waited for
1066 //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 +05301067 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001068 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001069
1070 pDevEntry.resetKvProcessingErrorIndication()
1071
1072 var wg sync.WaitGroup
1073 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001074 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1075 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001076
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001077 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001078 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001079}
1080
mpagenko15ff4a52021-03-02 10:09:20 +00001081//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1082// before this change here return like this was used:
1083// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1084//was and is called in background - error return does not make sense
1085func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1086 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1087 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001089 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001090 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001091 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301092 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001093 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001094 return
Himani Chawla4d908332020-08-31 12:30:20 +05301095 }
mpagenko01e726e2020-10-23 09:45:29 +00001096
1097 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001098 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001099
dbainbri4d3a0dc2020-12-02 00:33:42 +00001100 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001101 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001102 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001103 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001104 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001105 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001106 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001107 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001108 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001109 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001110 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001111 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001112 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1113 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1114 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1115 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001116}
1117
mpagenkoc8bba412021-01-15 15:38:44 +00001118//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001119func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1120 apDownloadManager *adapterDownloadManager) error {
1121 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001122 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001123
1124 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001125 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1126 if pDevEntry == nil {
1127 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1128 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1129 }
1130
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001131 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001132 var inactiveImageID uint16
1133 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1134 dh.lockUpgradeFsm.Lock()
1135 defer dh.lockUpgradeFsm.Unlock()
1136 if dh.pOnuUpradeFsm == nil {
1137 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1138 if err == nil {
1139 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1140 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1141 "device-id": dh.deviceID, "error": err})
1142 }
1143 } else {
1144 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001145 "device-id": dh.deviceID, "error": err})
1146 }
mpagenko15ff4a52021-03-02 10:09:20 +00001147 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1148 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1149 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1150 if pUpgradeStatemachine != nil {
1151 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1152 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1153 "device-id": dh.deviceID, "error": err})
1154 }
1155 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1156 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1157 // for now a second start of download should work again
1158 } else { //should never occur
1159 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1160 "device-id": dh.deviceID})
1161 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001162 }
mpagenko80622a52021-02-09 16:53:23 +00001163 }
mpagenko15ff4a52021-03-02 10:09:20 +00001164 } else {
1165 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1166 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001167 }
1168 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001169 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1170 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001171 }
1172 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001173}
1174
mpagenkoc26d4c02021-05-06 14:27:57 +00001175//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1176// after the OnuImage has been downloaded to the adapter, called in background
1177func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1178 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1179
1180 var err error
1181 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1182 if pDevEntry == nil {
1183 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1184 return
1185 }
1186
1187 var inactiveImageID uint16
1188 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1189 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1190 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1191 dh.lockUpgradeFsm.Lock()
1192 defer dh.lockUpgradeFsm.Unlock()
1193 if dh.pOnuUpradeFsm == nil {
1194 //OmciOnuSwUpgradeDone could be used to create some Kafka event with information on upgrade completion,
1195 // but none yet defined
1196 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1197 if err == nil {
1198 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
Holger Hildebrandtac010732021-06-02 13:35:39 +00001199 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00001200 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1201 "device-id": dh.deviceID, "error": err})
1202 return
1203 }
1204 } else {
1205 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1206 "device-id": dh.deviceID, "error": err})
1207 }
1208 return
1209 }
1210 //OnuSw upgrade already running - restart (with possible abort of running)
1211 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1212 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1213 if pUpgradeStatemachine != nil {
1214 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1215 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1216 "device-id": dh.deviceID, "error": err})
1217 return
1218 }
1219 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1220 // for now a second start of download should work again - must still be initiated by user
1221 } else { //should never occur
1222 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1223 "device-id": dh.deviceID})
1224 }
1225 return
1226 }
1227 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1228 "device-id": dh.deviceID, "error": err})
1229}
1230
1231//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001232func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1233 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001234 var err error
1235 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1236 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1237 // 2.) activation of the inactive image
1238
1239 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1240 if pDevEntry == nil {
1241 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001242 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001243 }
1244 dh.lockUpgradeFsm.RLock()
1245 if dh.pOnuUpradeFsm != nil {
1246 dh.lockUpgradeFsm.RUnlock()
1247 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1248 dh.deviceID, dh.deviceID)
1249 if getErr != nil || onuVolthaDevice == nil {
1250 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 +00001251 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001252 }
1253 // use the OnuVendor identification from this device for the internal unique name
1254 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1255 // 1.) check a started upgrade process and rely the activation request to it
1256 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001257 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001258 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1259 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001260 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001261 }
mpagenko183647c2021-06-08 15:25:04 +00001262 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1263 "device-id": dh.deviceID, "image-id": imageIdentifier})
1264 var pImageStates *voltha.ImageState
1265 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1266 pImageStates = &voltha.ImageState{}
1267 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1268 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1269 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1270 }
1271 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001272 } //else
1273 dh.lockUpgradeFsm.RUnlock()
1274
1275 // 2.) check if requested image-version equals the inactive one and start its activation
1276 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1277 var inactiveImageID uint16
1278 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1279 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1280 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001281 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001282 }
1283 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1284 if err == nil {
1285 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1286 inactiveImageID, aCommitRequest); err != nil {
1287 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1288 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001289 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001290 }
1291 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1292 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001293 var pImageStates *voltha.ImageState
1294 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1295 pImageStates := &voltha.ImageState{}
1296 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1297 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1298 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1299 }
1300 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001301 } //else
1302 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1303 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001304 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001305}
1306
1307//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001308func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1309 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001310 var err error
1311 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1312 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1313 // 2.) commitment of the active image
1314
1315 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1316 if pDevEntry == nil {
1317 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001318 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001319 }
1320 dh.lockUpgradeFsm.RLock()
1321 if dh.pOnuUpradeFsm != nil {
1322 dh.lockUpgradeFsm.RUnlock()
1323 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1324 dh.deviceID, dh.deviceID)
1325 if getErr != nil || onuVolthaDevice == nil {
1326 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 +00001327 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 }
1329 // use the OnuVendor identification from this device for the internal unique name
1330 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
1331 // 1.) check a started upgrade process and rely the commitment request to it
1332 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001333 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001334 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1335 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001336 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001337 }
mpagenko183647c2021-06-08 15:25:04 +00001338 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1339 "device-id": dh.deviceID, "image-id": imageIdentifier})
1340 var pImageStates *voltha.ImageState
1341 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1342 pImageStates := &voltha.ImageState{}
1343 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1344 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1345 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1346 }
1347 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001348 } //else
1349 dh.lockUpgradeFsm.RUnlock()
1350
mpagenko183647c2021-06-08 15:25:04 +00001351 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001352 var activeImageID uint16
1353 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1354 logger.Errorw(ctx, "get active image failed", log.Fields{
1355 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001356 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001357 }
1358 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1359 if err == nil {
1360 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1361 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1362 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001363 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001364 }
1365 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1366 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko183647c2021-06-08 15:25:04 +00001367 var pImageStates *voltha.ImageState
1368 if pImageStates, err = dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion); err != nil {
1369 pImageStates := &voltha.ImageState{}
1370 pImageStates.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1371 pImageStates.Reason = voltha.ImageState_UNKNOWN_ERROR
1372 pImageStates.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1373 }
1374 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001375 } //else
1376 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1377 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001378 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001379}
1380
mpagenkoaa3afe92021-05-21 16:20:58 +00001381func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
1382 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1383 pDeviceImageState.DeviceId = dh.deviceID
mpagenko183647c2021-06-08 15:25:04 +00001384 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001385 dh.lockUpgradeFsm.RLock()
1386 if dh.pOnuUpradeFsm != nil {
1387 dh.lockUpgradeFsm.RUnlock()
mpagenko183647c2021-06-08 15:25:04 +00001388 if pImageStates, err := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion); err == nil {
mpagenkoaa3afe92021-05-21 16:20:58 +00001389 pDeviceImageState.ImageState.DownloadState = pImageStates.DownloadState
1390 pDeviceImageState.ImageState.Reason = pImageStates.Reason
1391 pDeviceImageState.ImageState.ImageState = pImageStates.ImageState
1392 } else {
1393 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1394 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1395 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1396 }
1397 } else {
1398 dh.lockUpgradeFsm.RUnlock()
1399 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1400 if dh.upgradeSuccess {
1401 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_SUCCEEDED
1402 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_COMMITTED
1403 } else {
1404 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1405 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1406 }
1407 }
1408}
1409
1410func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1411 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1412 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001413 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001414 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1415 dh.lockUpgradeFsm.RLock()
1416 if dh.pOnuUpradeFsm != nil {
1417 dh.lockUpgradeFsm.RUnlock()
1418 //option: it could be also checked if the upgrade FSM is running on the given imageIdentifier or version
1419 // by now just straightforward assume this to be true
1420 dh.pOnuUpradeFsm.CancelProcessing(ctx)
1421 //nolint:misspell
1422 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_CANCELLED
1423 //nolint:misspell
1424 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
1425 } else {
1426 dh.lockUpgradeFsm.RUnlock()
1427 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1428 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
1429 }
1430}
1431
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001432func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1433
1434 var onuImageStatus *OnuImageStatus
1435
1436 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1437 if pDevEntry != nil {
1438 onuImageStatus = NewOnuImageStatus(pDevEntry)
1439 pDevEntry.mutexOnuImageStatus.Lock()
1440 pDevEntry.pOnuImageStatus = onuImageStatus
1441 pDevEntry.mutexOnuImageStatus.Unlock()
1442
1443 } else {
1444 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1445 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1446 }
1447 images, err := onuImageStatus.getOnuImageStatus(ctx)
1448 pDevEntry.mutexOnuImageStatus.Lock()
1449 pDevEntry.pOnuImageStatus = nil
1450 pDevEntry.mutexOnuImageStatus.Unlock()
1451 return images, err
1452}
1453
Himani Chawla6d2ae152020-09-02 13:11:20 +05301454// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001455// #####################################################################################
1456
1457// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301458// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001459
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1461 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 +00001462}
1463
1464// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001466
dbainbri4d3a0dc2020-12-02 00:33:42 +00001467 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001468 var err error
1469
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001470 // populate what we know. rest comes later after mib sync
1471 dh.device.Root = false
1472 dh.device.Vendor = "OpenONU"
1473 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001474 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001475 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001477 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001478
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001479 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001480 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1481 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301482 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001483 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001485 log.Fields{"device-id": dh.deviceID})
1486 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001487
Himani Chawla4d908332020-08-31 12:30:20 +05301488 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001489 dh.ponPortNumber = dh.device.ParentPortNo
1490
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001491 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1492 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1493 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001495 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301496 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001497
1498 /*
1499 self._pon = PonPort.create(self, self._pon_port_number)
1500 self._pon.add_peer(self.parent_id, self._pon_port_number)
1501 self.logger.debug('adding-pon-port-to-agent',
1502 type=self._pon.get_port().type,
1503 admin_state=self._pon.get_port().admin_state,
1504 oper_status=self._pon.get_port().oper_status,
1505 )
1506 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001507 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001509 var ponPortNo uint32 = 1
1510 if dh.ponPortNumber != 0 {
1511 ponPortNo = dh.ponPortNumber
1512 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001513
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001514 pPonPort := &voltha.Port{
1515 PortNo: ponPortNo,
1516 Label: fmt.Sprintf("pon-%d", ponPortNo),
1517 Type: voltha.Port_PON_ONU,
1518 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301519 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001520 PortNo: ponPortNo}}, // Peer port is parent's port number
1521 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1523 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001524 e.Cancel(err)
1525 return
1526 }
1527 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001528 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001529 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001531}
1532
1533// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001535
dbainbri4d3a0dc2020-12-02 00:33:42 +00001536 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001537 var err error
1538 /*
1539 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1540 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1541 return nil
1542 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1544 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001545 e.Cancel(err)
1546 return
1547 }
1548
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001549 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001551 // reconcilement will be continued after mib download is done
1552 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001553
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001554 /*
1555 ############################################################################
1556 # Setup Alarm handler
1557 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1558 device.serial_number)
1559 ############################################################################
1560 # Setup PM configuration for this device
1561 # Pass in ONU specific options
1562 kwargs = {
1563 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1564 'heartbeat': self.heartbeat,
1565 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1566 }
1567 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1568 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1569 self.logical_device_id, device.serial_number,
1570 grouped=True, freq_override=False, **kwargs)
1571 pm_config = self._pm_metrics.make_proto()
1572 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1573 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1574 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1575
1576 # Note, ONU ID and UNI intf set in add_uni_port method
1577 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1578 ani_ports=[self._pon])
1579
1580 # Code to Run OMCI Test Action
1581 kwargs_omci_test_action = {
1582 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1583 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1584 }
1585 serial_number = device.serial_number
1586 self._test_request = OmciTestRequest(self.core_proxy,
1587 self.omci_agent, self.device_id,
1588 AniG, serial_number,
1589 self.logical_device_id,
1590 exclusive=False,
1591 **kwargs_omci_test_action)
1592
1593 self.enabled = True
1594 else:
1595 self.logger.info('onu-already-activated')
1596 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001597
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599}
1600
1601// doStateConnected get the device info and update to voltha core
1602// for comparison of the original method (not that easy to uncomment): compare here:
1603// voltha-openolt-adapter/adaptercore/device_handler.go
1604// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301608 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001609 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001611}
1612
1613// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001615
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301617 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001618 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001620
1621 /*
1622 // Synchronous call to update device state - this method is run in its own go routine
1623 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1624 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001625 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 +00001626 return err
1627 }
1628 return nil
1629 */
1630}
1631
1632// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001633func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001634
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001636 var err error
1637
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001638 device := dh.device
1639 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001640 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001642 e.Cancel(err)
1643 return
1644 }
1645
1646 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001648 /*
1649 // Update the all ports state on that device to disable
1650 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001651 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001652 return er
1653 }
1654
1655 //Update the device oper state and connection status
1656 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1657 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1658 dh.device = cloned
1659
1660 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001661 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001662 return er
1663 }
1664
1665 //get the child device for the parent device
1666 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1667 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001668 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 return err
1670 }
1671 for _, onuDevice := range onuDevices.Items {
1672
1673 // Update onu state as down in onu adapter
1674 onuInd := oop.OnuIndication{}
1675 onuInd.OperState = "down"
1676 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1677 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1678 if er != nil {
1679 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001680 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001681 //Do not return here and continue to process other ONUs
1682 }
1683 }
1684 // * Discovered ONUs entries need to be cleared , since after OLT
1685 // is up, it starts sending discovery indications again* /
1686 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001687 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001688 return nil
1689 */
Himani Chawla4d908332020-08-31 12:30:20 +05301690 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001691 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001693}
1694
Himani Chawla6d2ae152020-09-02 13:11:20 +05301695// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001696// #################################################################################
1697
1698// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301699// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001701//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001703 dh.lockDevice.RLock()
1704 pOnuDeviceEntry := dh.pOnuOmciDevice
1705 if aWait && pOnuDeviceEntry == nil {
1706 //keep the read sema short to allow for subsequent write
1707 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001709 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1710 // so it might be needed to wait here for that event with some timeout
1711 select {
1712 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001714 return nil
1715 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001716 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001717 // if written now, we can return the written value without sema
1718 return dh.pOnuOmciDevice
1719 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001720 }
mpagenko3af1f032020-06-10 08:53:41 +00001721 dh.lockDevice.RUnlock()
1722 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001723}
1724
Himani Chawla6d2ae152020-09-02 13:11:20 +05301725//setOnuDeviceEntry sets the ONU device entry within the handler
1726func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001727 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001728 dh.lockDevice.Lock()
1729 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001730 dh.pOnuOmciDevice = apDeviceEntry
1731 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001732 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301733 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001734 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001735}
1736
Himani Chawla6d2ae152020-09-02 13:11:20 +05301737//addOnuDeviceEntry creates a new ONU device or returns the existing
1738func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001740
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001742 if deviceEntry == nil {
1743 /* costum_me_map in python code seems always to be None,
1744 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1745 /* also no 'clock' argument - usage open ...*/
1746 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001747 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001748 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001749 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301750 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001751 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001752 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001753 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001754 // fire deviceEntry ready event to spread to possibly waiting processing
1755 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001756 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001757 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001758 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001759 }
1760 // might be updated with some error handling !!!
1761 return nil
1762}
1763
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1765 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001766 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1767
1768 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001769
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001771 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001772 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001773 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1774 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001775 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 if err := dh.storePersistentData(ctx); err != nil {
1777 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001778 log.Fields{"device-id": dh.deviceID, "err": err})
1779 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001781 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001783 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1784 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001785 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001786 }
1787 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001788 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001789 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001790
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001791 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001792 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001793 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 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 +00001795 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001796 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001797 } else {
1798 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001799 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001801 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1802 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1803 // 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 +00001804 // 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 +00001805 // so let's just try to keep it simple ...
1806 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001808 if err != nil || device == nil {
1809 //TODO: needs to handle error scenarios
1810 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1811 return errors.New("Voltha Device not found")
1812 }
1813 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001814
dbainbri4d3a0dc2020-12-02 00:33:42 +00001815 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001816 return err
mpagenko3af1f032020-06-10 08:53:41 +00001817 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001818
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001819 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001820
1821 /* this might be a good time for Omci Verify message? */
1822 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001823 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001824 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001825 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001826 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001827
1828 /* give the handler some time here to wait for the OMCi verification result
1829 after Timeout start and try MibUpload FSM anyway
1830 (to prevent stopping on just not supported OMCI verification from ONU) */
1831 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001832 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001833 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001834 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001836 }
1837
1838 /* In py code it looks earlier (on activate ..)
1839 # Code to Run OMCI Test Action
1840 kwargs_omci_test_action = {
1841 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1842 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1843 }
1844 serial_number = device.serial_number
1845 self._test_request = OmciTestRequest(self.core_proxy,
1846 self.omci_agent, self.device_id,
1847 AniG, serial_number,
1848 self.logical_device_id,
1849 exclusive=False,
1850 **kwargs_omci_test_action)
1851 ...
1852 # Start test requests after a brief pause
1853 if not self._test_request_started:
1854 self._test_request_started = True
1855 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1856 reactor.callLater(tststart, self._test_request.start_collector)
1857
1858 */
1859 /* which is then: in omci_test_request.py : */
1860 /*
1861 def start_collector(self, callback=None):
1862 """
1863 Start the collection loop for an adapter if the frequency > 0
1864
1865 :param callback: (callable) Function to call to collect PM data
1866 """
1867 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1868 if callback is None:
1869 callback = self.perform_test_omci
1870
1871 if self.lc is None:
1872 self.lc = LoopingCall(callback)
1873
1874 if self.default_freq > 0:
1875 self.lc.start(interval=self.default_freq / 10)
1876
1877 def perform_test_omci(self):
1878 """
1879 Perform the initial test request
1880 """
1881 ani_g_entities = self._device.configuration.ani_g_entities
1882 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1883 is not None else None
1884 self._entity_id = ani_g_entities_ids[0]
1885 self.logger.info('perform-test', entity_class=self._entity_class,
1886 entity_id=self._entity_id)
1887 try:
1888 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1889 result = yield self._device.omci_cc.send(frame)
1890 if not result.fields['omci_message'].fields['success_code']:
1891 self.logger.info('Self-Test Submitted Successfully',
1892 code=result.fields[
1893 'omci_message'].fields['success_code'])
1894 else:
1895 raise TestFailure('Test Failure: {}'.format(
1896 result.fields['omci_message'].fields['success_code']))
1897 except TimeoutError as e:
1898 self.deferred.errback(failure.Failure(e))
1899
1900 except Exception as e:
1901 self.logger.exception('perform-test-Error', e=e,
1902 class_id=self._entity_class,
1903 entity_id=self._entity_id)
1904 self.deferred.errback(failure.Failure(e))
1905
1906 */
1907
1908 // PM related heartbeat??? !!!TODO....
1909 //self._heartbeat.enabled = True
1910
mpagenko1cc3cb42020-07-27 15:24:38 +00001911 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1912 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1913 * 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 +05301914 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001915 */
1916 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001917 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001918 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001919 if pMibUlFsm.Is(ulStDisabled) {
1920 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 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 +00001922 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301923 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301925 //Determine ONU status and start/re-start MIB Synchronization tasks
1926 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001927 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301928 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 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 +00001930 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001931 }
Himani Chawla4d908332020-08-31 12:30:20 +05301932 } else {
1933 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 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 +00001935 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301936 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001938 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001939 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001941 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001942 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001943 }
1944 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001946 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001947 }
1948 return nil
1949}
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001952 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001953 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001954 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001956
mpagenko900ee4b2020-10-12 11:56:34 +00001957 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1958 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1959 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001960 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001962 log.Fields{"device-id": dh.deviceID, "error": err})
1963 // abort: system behavior is just unstable ...
1964 return err
1965 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001966 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 _ = 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 +00001968
1969 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1970 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1971 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001973 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001974 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001975 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001978
1979 //TODO!!! remove existing traffic profiles
1980 /* from py code, if TP's exist, remove them - not yet implemented
1981 self._tp = dict()
1982 # Let TP download happen again
1983 for uni_id in self._tp_service_specific_task:
1984 self._tp_service_specific_task[uni_id].clear()
1985 for uni_id in self._tech_profile_download_done:
1986 self._tech_profile_download_done[uni_id].clear()
1987 */
1988
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001990
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001991 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001992
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001994 // abort: system behavior is just unstable ...
1995 return err
1996 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001998 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002000 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002001 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002003 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002004 // abort: system behavior is just unstable ...
2005 return err
2006 }
2007 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002009 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002010 return nil
2011}
2012
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002013func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002014 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2015 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2016 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2017 // and using the stop/reset event should never harm
2018
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002020 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002022 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2023 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002024 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002025 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002026 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002027 pDevEntry.mutexOnuImageStatus.RLock()
2028 if pDevEntry.pOnuImageStatus != nil {
2029 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2030 }
2031 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002032
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002033 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002034 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002035 }
2036 //MibDownload may run
2037 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2038 if pMibDlFsm != nil {
2039 _ = pMibDlFsm.Event(dlEvReset)
2040 }
2041 //port lock/unlock FSM's may be active
2042 if dh.pUnlockStateFsm != nil {
2043 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2044 }
2045 if dh.pLockStateFsm != nil {
2046 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2047 }
2048 //techProfile related PonAniConfigFsm FSM may be active
2049 if dh.pOnuTP != nil {
2050 // should always be the case here
2051 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2052 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002053 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002054 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002055 }
mpagenko900ee4b2020-10-12 11:56:34 +00002056 }
2057 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002058 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002059 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002060 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2061 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002062 dh.lockVlanConfig.RUnlock()
2063 //reset of all Fsm is always accompanied by global persistency data removal
2064 // no need to remove specific data
2065 pVlanFilterFsm.RequestClearPersistency(false)
2066 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002067 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002068 } else {
2069 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002070 }
2071 }
2072 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002073 if dh.getCollectorIsRunning() {
2074 // Stop collector routine
2075 dh.stopCollector <- true
2076 }
Himani Chawla1472c682021-03-17 17:11:14 +05302077 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302078 dh.stopAlarmManager <- true
2079 }
2080
mpagenko80622a52021-02-09 16:53:23 +00002081 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002082 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002083 dh.lockUpgradeFsm.RLock()
2084 if dh.pOnuUpradeFsm != nil {
mpagenkoc26d4c02021-05-06 14:27:57 +00002085 dh.pOnuUpradeFsm.CancelProcessing(ctx)
mpagenko80622a52021-02-09 16:53:23 +00002086 }
2087 dh.lockUpgradeFsm.RUnlock()
2088
mpagenko7d6bb022021-03-11 15:07:55 +00002089 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002090 return nil
2091}
2092
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2094 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 +05302095
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002096 // store persistent data collected during MIB upload processing
2097 if err := dh.storePersistentData(ctx); err != nil {
2098 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2099 log.Fields{"device-id": dh.deviceID, "err": err})
2100 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002101 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002102 dh.addAllUniPorts(ctx)
2103
mpagenkoa40e99a2020-11-17 13:50:39 +00002104 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2105 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2106 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2107 * disable/enable toggling here to allow traffic
2108 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2109 * like the py comment says:
2110 * # start by locking all the unis till mib sync and initial mib is downloaded
2111 * # this way we can capture the port down/up events when we are ready
2112 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302113
mpagenkoa40e99a2020-11-17 13:50:39 +00002114 // Init Uni Ports to Admin locked state
2115 // *** should generate UniLockStateDone event *****
2116 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002118 } else { //LockStateFSM already init
2119 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002121 }
2122}
2123
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2125 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302126 /* Mib download procedure -
2127 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2128 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002130 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002131 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002132 return
2133 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302134 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2135 if pMibDlFsm != nil {
2136 if pMibDlFsm.Is(dlStDisabled) {
2137 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002138 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 +05302139 // maybe try a FSM reset and then again ... - TODO!!!
2140 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302142 // maybe use more specific states here for the specific download steps ...
2143 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302145 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002146 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302147 //Begin MIB data download (running autonomously)
2148 }
2149 }
2150 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002152 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302153 // maybe try a FSM reset and then again ... - TODO!!!
2154 }
2155 /***** Mib download started */
2156 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302158 }
2159}
2160
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2162 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302163 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002164 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002166 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002167 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2168 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2169 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2170 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302172 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2173 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002174 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302175 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302177 }
2178 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302180 log.Fields{"device-id": dh.deviceID})
2181 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002182 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002183
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002184 if !dh.getCollectorIsRunning() {
2185 // Start PM collector routine
2186 go dh.startCollector(ctx)
2187 }
2188 if !dh.getAlarmManagerIsRunning(ctx) {
2189 go dh.startAlarmManager(ctx)
2190 }
2191
Girish Gowdrae0140f02021-02-02 16:55:09 -08002192 // Initialize classical L2 PM Interval Counters
2193 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2194 // There is no way we should be landing here, but if we do then
2195 // there is nothing much we can do about this other than log error
2196 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2197 }
2198
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002199 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002200
2201 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2202 if pDevEntry == nil {
2203 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2204 return
2205 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002206 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002207 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002208 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002209 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2210 log.Fields{"device-id": dh.deviceID})
2211 go dh.reconcileDeviceTechProf(ctx)
2212 // reconcilement will be continued after ani config is done
2213 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002214 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002215 // *** should generate UniUnlockStateDone event *****
2216 if dh.pUnlockStateFsm == nil {
2217 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2218 } else { //UnlockStateFSM already init
2219 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2220 dh.runUniLockFsm(ctx, false)
2221 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302222 }
2223}
2224
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2226 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302227
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002228 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002230 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002231 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2232 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002233 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002235 return
2236 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002237 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002238 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002239 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 if err := dh.storePersistentData(ctx); err != nil {
2241 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002242 log.Fields{"device-id": dh.deviceID, "err": err})
2243 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302244 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002245 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 +05302246 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002248 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302249 }
2250}
2251
dbainbri4d3a0dc2020-12-02 00:33:42 +00002252func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2253 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002254 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002256 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2257 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002259 }
2260
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002262 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002263 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002264
2265 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002267
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002269 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002271 return
2272 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002273 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002274 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002275 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 if err := dh.storePersistentData(ctx); err != nil {
2277 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002278 log.Fields{"device-id": dh.deviceID, "err": err})
2279 }
mpagenko900ee4b2020-10-12 11:56:34 +00002280}
2281
dbainbri4d3a0dc2020-12-02 00:33:42 +00002282func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2283 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002284 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002285 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002286 voltha.OperStatus_ACTIVE); err != nil {
2287 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002288 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002289 }
2290
dbainbri4d3a0dc2020-12-02 00:33:42 +00002291 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002292 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002293 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002294 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002295
2296 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002297 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002298
dbainbri4d3a0dc2020-12-02 00:33:42 +00002299 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002300 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002302 return
2303 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002304 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002305 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002306 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 if err := dh.storePersistentData(ctx); err != nil {
2308 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002309 log.Fields{"device-id": dh.deviceID, "err": err})
2310 }
mpagenko900ee4b2020-10-12 11:56:34 +00002311}
2312
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002314 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Debugw(ctx, "OmciAniConfigDone 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() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002319 // 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 +00002320 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302321 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002322 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002324 }
2325 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002326 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002327 // attention: the device reason update is done based on ONU-UNI-Port related activity
2328 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002329 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002330 // 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 +00002331 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002332 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002333 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302334}
2335
dbainbri4d3a0dc2020-12-02 00:33:42 +00002336func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2337 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002338 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302339 // attention: the device reason update is done based on ONU-UNI-Port related activity
2340 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302341
mpagenkof1fc3862021-02-16 10:09:52 +00002342 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002343 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002344 // which may be the case from some previous actvity on another UNI Port of the ONU
2345 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002346 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2347 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002348 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002349 }
2350 }
2351 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002352 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002353 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002355 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302356 }
mpagenkof1fc3862021-02-16 10:09:52 +00002357
2358 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2359 //events that request KvStore write
2360 if err := dh.storePersistentData(ctx); err != nil {
2361 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2362 log.Fields{"device-id": dh.deviceID, "err": err})
2363 }
2364 } else {
2365 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2366 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002367 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302368}
2369
Himani Chawla6d2ae152020-09-02 13:11:20 +05302370//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002371func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302372 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002373 case MibDatabaseSync:
2374 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002376 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002377 case UniLockStateDone:
2378 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002379 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002380 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002381 case MibDownloadDone:
2382 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002383 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002384 }
2385 case UniUnlockStateDone:
2386 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002388 }
mpagenko900ee4b2020-10-12 11:56:34 +00002389 case UniEnableStateDone:
2390 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002392 }
2393 case UniDisableStateDone:
2394 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002395 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002396 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002397 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002398 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002400 }
mpagenkof1fc3862021-02-16 10:09:52 +00002401 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002402 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002404 }
mpagenkoaa3afe92021-05-21 16:20:58 +00002405 case OmciOnuSwUpgradeDone:
2406 {
2407 dh.upgradeSuccess = true
2408 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002409 default:
2410 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002411 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002412 }
2413 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002414}
2415
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002417 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302419 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002420 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002422 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302423 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002425 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002427 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002428 //store UniPort with the System-PortNumber key
2429 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002430 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002431 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2433 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002434 } //error logging already within UniPort method
2435 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002437 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002438 }
2439 }
2440}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002441
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002442func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2443 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2444 if pDevEntry == nil {
2445 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2446 return
2447 }
2448 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2449 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2450 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2451 for _, mgmtEntityID := range pptpInstKeys {
2452 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2453 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2454 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2455 i++
2456 }
2457 } else {
2458 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2459 }
2460 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2461 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2462 for _, mgmtEntityID := range veipInstKeys {
2463 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2464 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2465 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2466 i++
2467 }
2468 } else {
2469 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2470 }
2471 if i == 0 {
2472 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2473 }
2474}
2475
mpagenko3af1f032020-06-10 08:53:41 +00002476// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002478 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302479 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002480 // with following remark:
2481 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2482 // # load on the core
2483
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002484 // 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 +00002485
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002486 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002487 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002488 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002489 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302490 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002491 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002492 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002493 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002494 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002496 }
mpagenko3af1f032020-06-10 08:53:41 +00002497 }
2498 }
2499}
2500
2501// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002503 // compare enableUniPortStateUpdate() above
2504 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2505 for uniNo, uniPort := range dh.uniEntityMap {
2506 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002507
2508 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002509 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302510 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002511 if !dh.isReconciling() {
2512 //maybe also use getter functions on uniPort - perhaps later ...
2513 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2514 } else {
2515 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2516 }
2517
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002518 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002519 }
2520}
2521
2522// ONU_Active/Inactive announcement on system KAFKA bus
2523// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002524func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002525 var de voltha.DeviceEvent
2526 eventContext := make(map[string]string)
2527 //Populating event context
2528 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002530 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002531 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302532 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002533 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 +00002534 }
2535 oltSerialNumber := parentDevice.SerialNumber
2536
2537 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2538 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2539 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302540 eventContext["olt-serial-number"] = oltSerialNumber
2541 eventContext["device-id"] = aDeviceID
2542 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002543 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2544 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2545 deviceEntry.mutexPersOnuConfig.RLock()
2546 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2547 deviceEntry.mutexPersOnuConfig.RUnlock()
2548 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2549 deviceEntry.mutexPersOnuConfig.RLock()
2550 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2551 deviceEntry.mutexPersOnuConfig.RUnlock()
2552 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2553 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2554 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2555 } else {
2556 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2557 log.Fields{"device-id": aDeviceID})
2558 return
2559 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002560
2561 /* Populating device event body */
2562 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302563 de.ResourceId = aDeviceID
2564 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002565 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2566 de.Description = fmt.Sprintf("%s Event - %s - %s",
2567 cEventObjectType, cOnuActivatedEvent, "Raised")
2568 } else {
2569 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2570 de.Description = fmt.Sprintf("%s Event - %s - %s",
2571 cEventObjectType, cOnuActivatedEvent, "Cleared")
2572 }
2573 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002574 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2575 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302576 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002577 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302579 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002580}
2581
Himani Chawla4d908332020-08-31 12:30:20 +05302582// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002583func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002584 chLSFsm := make(chan Message, 2048)
2585 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302586 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002587 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002588 sFsmName = "LockStateFSM"
2589 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002590 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002591 sFsmName = "UnLockStateFSM"
2592 }
mpagenko3af1f032020-06-10 08:53:41 +00002593
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002595 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002596 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002597 return
2598 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002599 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002600 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002601 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302602 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002603 dh.pLockStateFsm = pLSFsm
2604 } else {
2605 dh.pUnlockStateFsm = pLSFsm
2606 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002608 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002610 }
2611}
2612
2613// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002615 /* Uni Port lock/unlock procedure -
2616 ***** should run via 'adminDone' state and generate the argument requested event *****
2617 */
2618 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302619 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002620 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2621 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2622 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002623 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302624 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002625 }
2626 } else {
2627 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2628 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2629 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002630 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302631 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002632 }
2633 }
2634 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002635 if pLSStatemachine.Is(uniStDisabled) {
2636 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002637 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002638 // maybe try a FSM reset and then again ... - TODO!!!
2639 } else {
2640 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002642 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002643 }
2644 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002646 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002647 // maybe try a FSM reset and then again ... - TODO!!!
2648 }
2649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002651 // maybe try a FSM reset and then again ... - TODO!!!
2652 }
2653}
2654
mpagenko80622a52021-02-09 16:53:23 +00002655// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002656func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002657 //in here lockUpgradeFsm is already locked
2658 chUpgradeFsm := make(chan Message, 2048)
2659 var sFsmName = "OnuSwUpgradeFSM"
2660 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002661 if apDevEntry.PDevOmciCC == nil {
2662 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2663 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002664 }
mpagenko15ff4a52021-03-02 10:09:20 +00002665 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002666 sFsmName, chUpgradeFsm)
2667 if dh.pOnuUpradeFsm != nil {
2668 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2669 if pUpgradeStatemachine != nil {
2670 if pUpgradeStatemachine.Is(upgradeStDisabled) {
mpagenkoaa3afe92021-05-21 16:20:58 +00002671 dh.upgradeSuccess = false //for start of upgrade processing reset the last indication
mpagenko80622a52021-02-09 16:53:23 +00002672 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2673 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2674 // maybe try a FSM reset and then again ... - TODO!!!
2675 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2676 }
2677 /***** LockStateFSM started */
2678 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2679 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2680 } else {
2681 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2682 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2683 // maybe try a FSM reset and then again ... - TODO!!!
2684 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2685 }
2686 } else {
2687 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2688 // maybe try a FSM reset and then again ... - TODO!!!
2689 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2690 }
2691 } else {
2692 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2693 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2694 }
2695 return nil
2696}
2697
2698// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2699func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2700 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2701 "device-id": dh.deviceID})
2702 dh.lockUpgradeFsm.Lock()
2703 defer dh.lockUpgradeFsm.Unlock()
2704 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2705}
2706
mpagenko15ff4a52021-03-02 10:09:20 +00002707// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2708func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2709 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2710 if pDevEntry == nil {
2711 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2712 return
2713 }
2714
2715 dh.lockUpgradeFsm.RLock()
2716 defer dh.lockUpgradeFsm.RUnlock()
2717 if dh.pOnuUpradeFsm != nil {
2718 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2719 if pUpgradeStatemachine != nil {
2720 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2721 // (some manual forced commit could do without)
2722 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko183647c2021-06-08 15:25:04 +00002723 // 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 +00002724 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002725 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2726 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2727 return
2728 }
2729 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2730 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2731 } else {
2732 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2733 log.Fields{"device-id": dh.deviceID})
2734 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2735 return
2736 }
mpagenko183647c2021-06-08 15:25:04 +00002737 } else {
2738 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2739 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2740 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2741 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2742 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2743 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2744 dh.pOnuUpradeFsm.SetImageState(ctx, voltha.ImageState_IMAGE_ACTIVE)
2745 }
2746 }
mpagenko15ff4a52021-03-02 10:09:20 +00002747 }
2748 }
2749 } else {
2750 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2751 }
2752}
2753
Himani Chawla6d2ae152020-09-02 13:11:20 +05302754//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002756
2757 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002758 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002759 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002760 kvbackend := &db.Backend{
2761 Client: dh.pOpenOnuAc.kvClient,
2762 StoreType: dh.pOpenOnuAc.KVStoreType,
2763 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002764 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002765 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2766 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002767
mpagenkoaf801632020-07-03 10:00:42 +00002768 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002769}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002770func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302771 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002772
mpagenkodff5dda2020-08-28 11:52:01 +00002773 for _, field := range flow.GetOfbFields(apFlowItem) {
2774 switch field.Type {
2775 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2776 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002777 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002778 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2779 }
mpagenko01e726e2020-10-23 09:45:29 +00002780 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002781 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2782 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302783 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002784 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302785 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2786 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002787 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2788 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002789 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2790 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302791 return
mpagenkodff5dda2020-08-28 11:52:01 +00002792 }
2793 }
mpagenko01e726e2020-10-23 09:45:29 +00002794 */
mpagenkodff5dda2020-08-28 11:52:01 +00002795 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2796 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302797 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002798 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302799 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002800 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302801 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002802 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002803 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302804 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002805 }
2806 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2807 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302808 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002810 "PCP": loAddPcp})
2811 }
2812 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2813 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002814 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002815 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2816 }
2817 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2818 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002820 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2821 }
2822 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2823 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002824 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002825 "IPv4-DST": field.GetIpv4Dst()})
2826 }
2827 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2828 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002830 "IPv4-SRC": field.GetIpv4Src()})
2831 }
2832 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2833 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002834 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002835 "Metadata": field.GetTableMetadata()})
2836 }
2837 /*
2838 default:
2839 {
2840 //all other entires ignored
2841 }
2842 */
2843 }
2844 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302845}
mpagenkodff5dda2020-08-28 11:52:01 +00002846
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002848 for _, action := range flow.GetActions(apFlowItem) {
2849 switch action.Type {
2850 /* not used:
2851 case of.OfpActionType_OFPAT_OUTPUT:
2852 {
mpagenko01e726e2020-10-23 09:45:29 +00002853 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002854 "Output": action.GetOutput()})
2855 }
2856 */
2857 case of.OfpActionType_OFPAT_PUSH_VLAN:
2858 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002859 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002860 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2861 }
2862 case of.OfpActionType_OFPAT_SET_FIELD:
2863 {
2864 pActionSetField := action.GetSetField()
2865 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002867 "OxcmClass": pActionSetField.Field.OxmClass})
2868 }
2869 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302870 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302872 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002873 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302874 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302876 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002877 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002878 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002879 "Type": pActionSetField.Field.GetOfbField().Type})
2880 }
2881 }
2882 /*
2883 default:
2884 {
2885 //all other entires ignored
2886 }
2887 */
2888 }
2889 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302890}
2891
2892//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302894 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2895 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2896 var loAddPcp, loSetPcp uint8
2897 var loIPProto uint32
2898 /* the TechProfileId is part of the flow Metadata - compare also comment within
2899 * OLT-Adapter:openolt_flowmgr.go
2900 * Metadata 8 bytes:
2901 * Most Significant 2 Bytes = Inner VLAN
2902 * Next 2 Bytes = Tech Profile ID(TPID)
2903 * Least Significant 4 Bytes = Port ID
2904 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2905 * subscriber related flows.
2906 */
2907
dbainbri4d3a0dc2020-12-02 00:33:42 +00002908 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302909 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302911 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002912 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302913 }
mpagenko551a4d42020-12-08 18:09:20 +00002914 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002915 loCookie := apFlowItem.GetCookie()
2916 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002917 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002918 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302919
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002921 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302922 if loIPProto == 2 {
2923 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2924 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002925 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2926 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302927 return nil
2928 }
mpagenko01e726e2020-10-23 09:45:29 +00002929 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002930 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002931
2932 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002934 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2935 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2936 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2937 //TODO!!: Use DeviceId within the error response to rwCore
2938 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002939 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002940 }
2941 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002942 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002943 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2944 } else {
2945 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2946 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2947 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302948 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002949 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002950 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002951 }
mpagenko9a304ea2020-12-16 15:54:01 +00002952
2953 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002954 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002955 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302956 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002957 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002958 loMatchVlan, loSetVlan, loSetPcp, false)
mpagenkof1fc3862021-02-16 10:09:52 +00002959 dh.lockVlanConfig.RUnlock()
2960 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002961 }
mpagenkof1fc3862021-02-16 10:09:52 +00002962 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002963 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02002964 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false)
mpagenko01e726e2020-10-23 09:45:29 +00002965}
2966
2967//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002968func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002969 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2970 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2971 //no extra check is done on the rule parameters
2972 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2973 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2974 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2975 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002976 // - 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 +00002977 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002978 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002979
2980 /* TT related temporary workaround - should not be needed anymore
2981 for _, field := range flow.GetOfbFields(apFlowItem) {
2982 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2983 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002984 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002985 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2986 if loIPProto == 2 {
2987 // 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 +00002988 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002989 log.Fields{"device-id": dh.deviceID})
2990 return nil
2991 }
2992 }
2993 } //for all OfbFields
2994 */
2995
mpagenko9a304ea2020-12-16 15:54:01 +00002996 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002997 dh.lockVlanConfig.RLock()
2998 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002999 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003000 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003001 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003002 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003003 log.Fields{"device-id": dh.deviceID})
3004 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003005 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003006 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003007
mpagenko01e726e2020-10-23 09:45:29 +00003008 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003009}
3010
Himani Chawla26e555c2020-08-31 12:30:20 +05303011// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003012// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003013func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02003014 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003015 chVlanFilterFsm := make(chan Message, 2048)
3016
dbainbri4d3a0dc2020-12-02 00:33:42 +00003017 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003018 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003019 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303020 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003021 }
3022
dbainbri4d3a0dc2020-12-02 00:33:42 +00003023 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003024 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02003025 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile)
mpagenkodff5dda2020-08-28 11:52:01 +00003026 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00003027 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00003028 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
3029 // (from parallel processing)
3030 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303031 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003032 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3033 if pVlanFilterStatemachine != nil {
3034 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3035 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003036 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303037 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003038 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303039 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003040 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303041 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3042 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003043 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003044 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003045 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303046 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003047 }
3048 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003049 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003050 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303051 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003052 }
3053 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003054 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003055 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303056 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003057 }
3058 return nil
3059}
3060
mpagenkofc4f56e2020-11-04 17:17:49 +00003061//VerifyVlanConfigRequest checks on existence of a given uniPort
3062// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003063func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003064 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3065 var pCurrentUniPort *onuUniPort
3066 for _, uniPort := range dh.uniEntityMap {
3067 // only if this port is validated for operState transfer
3068 if uniPort.uniID == uint8(aUniID) {
3069 pCurrentUniPort = uniPort
3070 break //found - end search loop
3071 }
3072 }
3073 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003074 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003075 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3076 return
3077 }
mpagenko551a4d42020-12-08 18:09:20 +00003078 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003079}
3080
mpagenkodff5dda2020-08-28 11:52:01 +00003081//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003082func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003083 //TODO!! verify and start pending flow configuration
3084 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3085 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003086
3087 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303088 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003089 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003090 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3091 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3092 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003093 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
3094 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
3095 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3096 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3097 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3098 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3099 } else {
3100 /***** UniVlanConfigFsm continued */
3101 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3102 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3103 "UniPort": apUniPort.portNo})
3104 }
3105 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3106 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3107 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3108 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3109 } else {
3110 /***** UniVlanConfigFsm continued */
3111 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3112 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3113 "UniPort": apUniPort.portNo})
3114 }
mpagenkodff5dda2020-08-28 11:52:01 +00003115 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003116 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3117 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003118 "UniPort": apUniPort.portNo})
3119 }
3120 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003121 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3122 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3123 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003124 }
3125 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003126 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003127 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003128 }
mpagenkof1fc3862021-02-16 10:09:52 +00003129 } else {
3130 dh.lockVlanConfig.RUnlock()
3131 }
mpagenkodff5dda2020-08-28 11:52:01 +00003132}
3133
3134//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3135// 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 +00003136func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3137 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003138 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3139 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003140 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303141 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003142 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003143}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003144
mpagenkof1fc3862021-02-16 10:09:52 +00003145//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3146func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3147 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3148 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3149 // obviously then parallel processing on the cancel must be avoided
3150 // deadline context to ensure completion of background routines waited for
3151 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3152 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3153 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3154
3155 aPDevEntry.resetKvProcessingErrorIndication()
3156 var wg sync.WaitGroup
3157 wg.Add(1) // for the 1 go routine to finish
3158
3159 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3160 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3161
3162 return aPDevEntry.getKvProcessingErrorIndication()
3163}
3164
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003165//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3166//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003167func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3168 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003169
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003170 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003171 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003172 return nil
3173 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003174 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003175
dbainbri4d3a0dc2020-12-02 00:33:42 +00003176 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003177 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003178 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003179 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3180 }
3181 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3182
mpagenkof1fc3862021-02-16 10:09:52 +00003183 if aWriteToKvStore {
3184 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3185 }
3186 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003187}
3188
dbainbri4d3a0dc2020-12-02 00:33:42 +00003189func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003190 defer cancel() //ensure termination of context (may be pro forma)
3191 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003192 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003193 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003194}
3195
dbainbri4d3a0dc2020-12-02 00:33:42 +00003196func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003197
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003198 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003199 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003200 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003201 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3202 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003203 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003204 return err
3205 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003206 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003207 return nil
3208 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003209 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003210 return nil
3211}
3212
dbainbri4d3a0dc2020-12-02 00:33:42 +00003213func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3214 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003215 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003216 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003217 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3218 }
mpagenkof1fc3862021-02-16 10:09:52 +00003219 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003220}
3221
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003222func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
3223 var errStr string = ""
3224 for _, err := range errS {
3225 if err != nil {
3226 errStr = errStr + err.Error() + " "
3227 }
3228 }
3229 if errStr != "" {
3230 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
3231 }
3232 return nil
3233}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003234
3235// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003236// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003237func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3238 dh.lockDevice.RLock()
3239 defer dh.lockDevice.RUnlock()
3240 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3241 return uniPort.entityID, nil
3242 }
3243 return 0, errors.New("error-fetching-uni-port")
3244}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003245
3246// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003247func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3248 var errorsList []error
3249 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 -08003250
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003251 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3252 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3253 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3254
3255 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3256 // successfully.
3257 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3258 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3259 if len(errorsList) > 0 {
3260 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3261 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003262 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003263 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3264 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003265}
3266
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003267func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3268 var err error
3269 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003270 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003271
3272 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3273 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3274 errorsList = append(errorsList, err)
3275 }
3276 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003277 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003278
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003279 return errorsList
3280}
3281
3282func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3283 var err error
3284 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003285 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003286 // Check if group metric related config is updated
3287 for _, v := range pmConfigs.Groups {
3288 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3289 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3290 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3291
3292 if ok && m.frequency != v.GroupFreq {
3293 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3294 errorsList = append(errorsList, err)
3295 }
3296 }
3297 if ok && m.enabled != v.Enabled {
3298 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3299 errorsList = append(errorsList, err)
3300 }
3301 }
3302 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003303 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003304 return errorsList
3305}
3306
3307func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3308 var err error
3309 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003310 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003311 // Check if standalone metric related config is updated
3312 for _, v := range pmConfigs.Metrics {
3313 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003314 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003315 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3316
3317 if ok && m.frequency != v.SampleFreq {
3318 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3319 errorsList = append(errorsList, err)
3320 }
3321 }
3322 if ok && m.enabled != v.Enabled {
3323 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3324 errorsList = append(errorsList, err)
3325 }
3326 }
3327 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003328 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003329 return errorsList
3330}
3331
3332// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003333func (dh *deviceHandler) startCollector(ctx context.Context) {
3334 logger.Debugf(ctx, "startingCollector")
3335
3336 // Start routine to process OMCI GET Responses
3337 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003338 // Initialize the next metric collection time.
3339 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3340 // reset like onu rebooted.
3341 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003342 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003343 for {
3344 select {
3345 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003346 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003347 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003348 // Stop the L2 PM FSM
3349 go func() {
3350 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3351 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3352 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3353 }
3354 } else {
3355 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3356 }
3357 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003358 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3359 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3360 }
3361 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3362 dh.pOnuMetricsMgr.stopTicks <- true
3363 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003364
Girish Gowdrae09a6202021-01-12 18:10:59 -08003365 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003366 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3367 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3368 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3369 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3370 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003371 // Update the next metric collection time.
3372 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003373 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003374 } else {
3375 if dh.pmConfigs.Grouped { // metrics are managed as a group
3376 // parse through the group and standalone metrics to see it is time to collect their metrics
3377 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003378
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003379 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3380 // 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 -08003381 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3382 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003383 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3384 }
3385 }
3386 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3387 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3388 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3389 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3390 }
3391 }
3392 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3393
3394 // parse through the group and update the next metric collection time
3395 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3396 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3397 // 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 -08003398 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3399 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003400 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3401 }
3402 }
3403 // parse through the standalone metrics and update the next metric collection time
3404 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3405 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3406 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3407 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3408 }
3409 }
3410 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3411 } /* else { // metrics are not managed as a group
3412 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3413 } */
3414 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003415 }
3416 }
3417}
kesavandfdf77632021-01-26 23:40:33 -05003418
3419func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3420
3421 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3422 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3423}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003424
mpagenkof1fc3862021-02-16 10:09:52 +00003425func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3426 if pFsm == nil {
3427 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003428 }
mpagenkof1fc3862021-02-16 10:09:52 +00003429 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003430}
3431
mpagenkof1fc3862021-02-16 10:09:52 +00003432func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3433 var pFsm *fsm.FSM
3434 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3435 switch omciFsm {
3436 case cUploadFsm:
3437 {
3438 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3439 }
3440 case cDownloadFsm:
3441 {
3442 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3443 }
3444 case cUniLockFsm:
3445 {
3446 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3447 }
3448 case cUniUnLockFsm:
3449 {
3450 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3451 }
3452 case cL2PmFsm:
3453 {
3454 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3455 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3456 } else {
3457 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003458 }
3459 }
mpagenko80622a52021-02-09 16:53:23 +00003460 case cOnuUpgradeFsm:
3461 {
3462 dh.lockUpgradeFsm.RLock()
3463 defer dh.lockUpgradeFsm.RUnlock()
3464 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3465 }
mpagenkof1fc3862021-02-16 10:09:52 +00003466 default:
3467 {
3468 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3469 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3470 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003471 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003472 }
mpagenkof1fc3862021-02-16 10:09:52 +00003473 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003474}
3475
mpagenkof1fc3862021-02-16 10:09:52 +00003476func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3477 for _, v := range dh.pOnuTP.pAniConfigFsm {
3478 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003479 return false
3480 }
3481 }
3482 return true
3483}
3484
mpagenkof1fc3862021-02-16 10:09:52 +00003485func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3486 dh.lockVlanConfig.RLock()
3487 defer dh.lockVlanConfig.RUnlock()
3488 for _, v := range dh.UniVlanConfigFsmMap {
3489 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3490 return false
3491 }
3492 }
3493 return true //FSM not active - so there is no activity on omci
3494}
3495
3496func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3497 dh.lockVlanConfig.RLock()
3498 defer dh.lockVlanConfig.RUnlock()
3499 for _, v := range dh.UniVlanConfigFsmMap {
3500 if v.pAdaptFsm.pFsm != nil {
3501 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3502 return true //there is at least one VLAN FSM with some active configuration
3503 }
3504 }
3505 }
3506 return false //there is no VLAN FSM with some active configuration
3507}
3508
3509func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3510 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3511 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3512 return false
3513 }
3514 }
3515 // a further check is done to identify, if at least some data traffic related configuration exists
3516 // 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])
3517 return dh.checkUserServiceExists(ctx)
3518}
3519
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003520func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3521 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3522 if err := dh.resetFsms(ctx, false); err != nil {
3523 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3524 // TODO: fatal error reset ONU, delete deviceHandler!
3525 return
3526 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003527 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003528 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003529}
3530
3531func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3532 dh.mutexCollectorFlag.Lock()
3533 dh.collectorIsRunning = flagValue
3534 dh.mutexCollectorFlag.Unlock()
3535}
3536
3537func (dh *deviceHandler) getCollectorIsRunning() bool {
3538 dh.mutexCollectorFlag.RLock()
3539 flagValue := dh.collectorIsRunning
3540 dh.mutexCollectorFlag.RUnlock()
3541 return flagValue
3542}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303543
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303544func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3545 dh.mutextAlarmManagerFlag.Lock()
3546 dh.alarmManagerIsRunning = flagValue
3547 dh.mutextAlarmManagerFlag.Unlock()
3548}
3549
Himani Chawla1472c682021-03-17 17:11:14 +05303550func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303551 dh.mutextAlarmManagerFlag.RLock()
3552 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303553 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303554 dh.mutextAlarmManagerFlag.RUnlock()
3555 return flagValue
3556}
3557
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303558func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3559 logger.Debugf(ctx, "startingAlarmManager")
3560
3561 // Start routine to process OMCI GET Responses
3562 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303563 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303564 if stop := <-dh.stopAlarmManager; stop {
3565 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303566 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303567 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303568 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3569 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3570 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303571 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303572 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303573 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3574 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303575 }
3576}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003577
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003578func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003579 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003580
Maninder7961d722021-06-16 22:10:28 +05303581 connectStatus := voltha.ConnectStatus_UNREACHABLE
3582 operState := voltha.OperStatus_UNKNOWN
3583
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003584 if !dh.isReconciling() {
3585 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003586 logger.Debugw(ctx, "wait for channel signal or timeout",
3587 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003588 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003589 case success := <-dh.chReconcilingFinished:
3590 if success {
Maninderb5187552021-03-23 22:23:42 +05303591 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3592 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3593 log.Fields{"device-id": dh.deviceID})
3594 } else {
Maninderb5187552021-03-23 22:23:42 +05303595 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3596 connectStatus = voltha.ConnectStatus_REACHABLE
3597 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3598 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3599 operState = voltha.OperStatus_ACTIVE
3600 } else {
3601 operState = voltha.OperStatus_ACTIVATING
3602 }
3603 }
3604 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3605 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3606 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3607 operState = voltha.OperStatus_DISCOVERED
3608 }
3609
3610 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303611 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003612 logger.Debugw(ctx, "reconciling has been finished in time",
3613 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303614 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3615 logger.Errorw(ctx, "unable to update device state to core",
3616 log.Fields{"device-id": dh.deviceID, "Err": err})
3617 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003618 } else {
Maninderb5187552021-03-23 22:23:42 +05303619 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003620 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303621
3622 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3623 logger.Errorw(ctx, "No valid OnuDevice",
3624 log.Fields{"device-id": dh.deviceID})
3625 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3626 connectStatus = voltha.ConnectStatus_REACHABLE
3627 }
3628
3629 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003630 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003631 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003632 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3633 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303634
3635 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3636 logger.Errorw(ctx, "No valid OnuDevice",
3637 log.Fields{"device-id": dh.deviceID})
3638 } else if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3639 connectStatus = voltha.ConnectStatus_REACHABLE
3640 }
3641
3642 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
3643
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003644 }
3645 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003646 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003647 dh.mutexReconcilingFlag.Unlock()
3648 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003649 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003650 dh.mutexReconcilingFlag.Lock()
3651 if skipOnuConfig {
3652 dh.reconciling = cSkipOnuConfigReconciling
3653 } else {
3654 dh.reconciling = cOnuConfigReconciling
3655 }
3656 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003657}
3658
Girish Gowdra50e56422021-06-01 16:46:04 -07003659func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3660 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003661 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003662 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003663 } else {
3664 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3665 }
3666}
3667
3668func (dh *deviceHandler) isReconciling() bool {
3669 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003670 defer dh.mutexReconcilingFlag.RUnlock()
3671 return dh.reconciling != cNoReconciling
3672}
3673
3674func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3675 dh.mutexReconcilingFlag.RLock()
3676 defer dh.mutexReconcilingFlag.RUnlock()
3677 return dh.reconciling == cSkipOnuConfigReconciling
3678}
3679
3680func (dh *deviceHandler) setDeviceReason(value uint8) {
3681 dh.mutexDeviceReason.Lock()
3682 dh.deviceReason = value
3683 dh.mutexDeviceReason.Unlock()
3684}
3685
3686func (dh *deviceHandler) getDeviceReason() uint8 {
3687 dh.mutexDeviceReason.RLock()
3688 value := dh.deviceReason
3689 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003690 return value
3691}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003692
3693func (dh *deviceHandler) getDeviceReasonString() string {
3694 return deviceReasonMap[dh.getDeviceReason()]
3695}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003696
3697func (dh *deviceHandler) setReconcilingFlows(value bool) {
3698 dh.mutexReconcilingFlowsFlag.Lock()
3699 dh.reconcilingFlows = value
3700 dh.mutexReconcilingFlowsFlag.Unlock()
3701}
3702
3703func (dh *deviceHandler) isReconcilingFlows() bool {
3704 dh.mutexReconcilingFlowsFlag.RLock()
3705 value := dh.reconcilingFlows
3706 dh.mutexReconcilingFlowsFlag.RUnlock()
3707 return value
3708}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003709
3710func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3711 dh.mutexReadyForOmciConfig.Lock()
3712 dh.readyForOmciConfig = flagValue
3713 dh.mutexReadyForOmciConfig.Unlock()
3714}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003715func (dh *deviceHandler) isReadyForOmciConfig() bool {
3716 dh.mutexReadyForOmciConfig.RLock()
3717 flagValue := dh.readyForOmciConfig
3718 dh.mutexReadyForOmciConfig.RUnlock()
3719 return flagValue
3720}
Maninder7961d722021-06-16 22:10:28 +05303721
3722func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3723 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3724 logger.Errorw(ctx, "unable to update device reason to core",
3725 log.Fields{"device-id": dh.deviceID, "Err": err})
3726 }
3727
3728 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3729 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3730 logger.Errorw(ctx, "unable to update device state to core",
3731 log.Fields{"device-id": dh.deviceID, "Err": err})
3732 }
3733}