blob: 929d81d7450d8f51327aa35abba637788ff96aa1 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022 "errors"
23 "fmt"
Holger Hildebrandt24d51952020-05-04 14:03:42 +000024 "strconv"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025 "sync"
26 "time"
27
mpagenko1f8e8822021-06-25 14:10:21 +000028 "github.com/opencord/voltha-protos/v4/go/tech_profile"
29
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000030 "github.com/gogo/protobuf/proto"
31 "github.com/golang/protobuf/ptypes"
32 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000033 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070034 "github.com/opencord/voltha-lib-go/v5/pkg/adapters/adapterif"
35 "github.com/opencord/voltha-lib-go/v5/pkg/db"
36 "github.com/opencord/voltha-lib-go/v5/pkg/events/eventif"
37 flow "github.com/opencord/voltha-lib-go/v5/pkg/flows"
38 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050040 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000041 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
42 "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
44 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
45 oop "github.com/opencord/voltha-protos/v4/go/openolt"
46 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000047)
48
mpagenko9c225032021-10-15 14:26:49 +000049// Constants for timeouts
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000050const (
mpagenko9c225032021-10-15 14:26:49 +000051 cTimeOutRemoveUpgrade = 1 //for usage in seconds
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000052)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000053
mpagenko1cc3cb42020-07-27 15:24:38 +000054const (
55 // events of Device FSM
56 devEvDeviceInit = "devEvDeviceInit"
57 devEvGrpcConnected = "devEvGrpcConnected"
58 devEvGrpcDisconnected = "devEvGrpcDisconnected"
59 devEvDeviceUpInd = "devEvDeviceUpInd"
60 devEvDeviceDownInd = "devEvDeviceDownInd"
61)
62const (
63 // states of Device FSM
64 devStNull = "devStNull"
65 devStDown = "devStDown"
66 devStInit = "devStInit"
67 devStConnected = "devStConnected"
68 devStUp = "devStUp"
69)
70
Holger Hildebrandt24d51952020-05-04 14:03:42 +000071//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
72const (
Himani Chawla4d908332020-08-31 12:30:20 +053073 pon = voltha.EventSubCategory_PON
74 //olt = voltha.EventSubCategory_OLT
75 //ont = voltha.EventSubCategory_ONT
76 //onu = voltha.EventSubCategory_ONU
77 //nni = voltha.EventSubCategory_NNI
78 //service = voltha.EventCategory_SERVICE
79 //security = voltha.EventCategory_SECURITY
80 equipment = voltha.EventCategory_EQUIPMENT
81 //processing = voltha.EventCategory_PROCESSING
82 //environment = voltha.EventCategory_ENVIRONMENT
83 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000084)
85
86const (
87 cEventObjectType = "ONU"
88)
89const (
90 cOnuActivatedEvent = "ONU_ACTIVATED"
91)
92
Holger Hildebrandt10d98192021-01-27 15:29:31 +000093type usedOmciConfigFsms int
94
95const (
96 cUploadFsm usedOmciConfigFsms = iota
97 cDownloadFsm
98 cUniLockFsm
99 cUniUnLockFsm
100 cAniConfigFsm
101 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800102 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000103 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000104)
105
mpagenkof1fc3862021-02-16 10:09:52 +0000106type omciIdleCheckStruct struct {
107 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
108 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000109}
110
mpagenkof1fc3862021-02-16 10:09:52 +0000111var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
112 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
113 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
114 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
115 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
117 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
118 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000119 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000120}
121
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000122const (
123 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000124 drUnset = 0
125 drActivatingOnu = 1
126 drStartingOpenomci = 2
127 drDiscoveryMibsyncComplete = 3
128 drInitialMibDownloaded = 4
129 drTechProfileConfigDownloadSuccess = 5
130 drOmciFlowsPushed = 6
131 drOmciAdminLock = 7
132 drOnuReenabled = 8
133 drStoppingOpenomci = 9
134 drRebooting = 10
135 drOmciFlowsDeleted = 11
136 drTechProfileConfigDeleteSuccess = 12
Maninder7961d722021-06-16 22:10:28 +0530137 drReconcileFailed = 13
138 drReconcileMaxTimeout = 14
139 drReconcileCanceled = 15
Girish Gowdra50e56422021-06-01 16:46:04 -0700140 drTechProfileConfigDownloadFailed = 16
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000141)
142
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000143var deviceReasonMap = map[uint8]string{
144 drUnset: "unset",
145 drActivatingOnu: "activating-onu",
146 drStartingOpenomci: "starting-openomci",
147 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
148 drInitialMibDownloaded: "initial-mib-downloaded",
149 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
Girish Gowdra50e56422021-06-01 16:46:04 -0700150 drTechProfileConfigDownloadFailed: "tech-profile-config-download-failed",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000151 drOmciFlowsPushed: "omci-flows-pushed",
152 drOmciAdminLock: "omci-admin-lock",
153 drOnuReenabled: "onu-reenabled",
154 drStoppingOpenomci: "stopping-openomci",
155 drRebooting: "rebooting",
156 drOmciFlowsDeleted: "omci-flows-deleted",
157 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
Maninder7961d722021-06-16 22:10:28 +0530158 drReconcileFailed: "reconcile-failed",
159 drReconcileMaxTimeout: "reconcile-max-timeout",
160 drReconcileCanceled: "reconciling-canceled",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000161}
162
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000163const (
164 cNoReconciling = iota
165 cOnuConfigReconciling
166 cSkipOnuConfigReconciling
167)
168
Himani Chawla6d2ae152020-09-02 13:11:20 +0530169//deviceHandler will interact with the ONU ? device.
170type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000171 deviceID string
172 DeviceType string
173 adminState string
174 device *voltha.Device
175 logicalDeviceID string
176 ProxyAddressID string
177 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530178 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000179 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000181 coreProxy adapterif.CoreProxy
182 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530183 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000184
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800185 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800186
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000187 pOpenOnuAc *OpenONUAC
188 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530189 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000190 deviceEntrySet chan bool //channel for DeviceEntry set event
191 pOnuOmciDevice *OnuDeviceEntry
192 pOnuTP *onuUniTechProf
193 pOnuMetricsMgr *onuMetricsManager
194 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700195 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000196 exitChannel chan int
197 lockDevice sync.RWMutex
198 pOnuIndication *oop.OnuIndication
199 deviceReason uint8
200 mutexDeviceReason sync.RWMutex
201 pLockStateFsm *lockStateFsm
202 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000203
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000204 //flowMgr *OpenOltFlowMgr
205 //eventMgr *OpenOltEventMgr
206 //resourceMgr *rsrcMgr.OpenOltResourceMgr
207
208 //discOnus sync.Map
209 //onus sync.Map
210 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000211 collectorIsRunning bool
212 mutexCollectorFlag sync.RWMutex
213 stopCollector chan bool
214 alarmManagerIsRunning bool
215 mutextAlarmManagerFlag sync.RWMutex
216 stopAlarmManager chan bool
217 stopHeartbeatCheck chan bool
218 uniEntityMap map[uint32]*onuUniPort
219 mutexKvStoreContext sync.Mutex
220 lockVlanConfig sync.RWMutex
mpagenko2f487262021-08-23 15:59:06 +0000221 lockVlanAdd sync.RWMutex
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000222 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
223 lockUpgradeFsm sync.RWMutex
224 pOnuUpradeFsm *OnuUpgradeFsm
mpagenko9c225032021-10-15 14:26:49 +0000225 upgradeCanceled bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000226 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
mpagenko9c225032021-10-15 14:26:49 +0000236 pLastUpgradeImageState *voltha.ImageState
237 upgradeFsmChan chan struct{}
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238}
239
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530241func 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 +0530242 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000243 dh.coreProxy = cp
244 dh.AdapterProxy = ap
245 dh.EventProxy = ep
246 cloned := (proto.Clone(device)).(*voltha.Device)
247 dh.deviceID = cloned.Id
248 dh.DeviceType = cloned.Type
249 dh.adminState = "up"
250 dh.device = cloned
251 dh.pOpenOnuAc = adapter
252 dh.exitChannel = make(chan int, 1)
253 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000254 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000255 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000256 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530257 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530258 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000259 dh.stopHeartbeatCheck = make(chan bool, 2)
260 //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 +0000261 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530262 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000263 dh.lockVlanConfig = sync.RWMutex{}
mpagenko2f487262021-08-23 15:59:06 +0000264 dh.lockVlanAdd = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000265 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000266 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000267 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000268 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000269 dh.reconcilingFlows = false
270 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000271 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000272 dh.deletionInProgress = false
mpagenko9c225032021-10-15 14:26:49 +0000273 dh.pLastUpgradeImageState = &voltha.ImageState{
274 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
275 Reason: voltha.ImageState_UNKNOWN_ERROR,
276 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
277 }
278 dh.upgradeFsmChan = make(chan struct{})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000279
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800280 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
281 dh.pmConfigs = cloned.PmConfigs
282 } /* else {
283 // will be populated when onu_metrics_mananger is initialized.
284 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800285
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 // Device related state machine
287 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000288 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000290 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
291 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
292 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
293 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
294 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 },
296 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
298 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
299 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
300 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
301 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
302 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
303 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
304 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000305 },
306 )
mpagenkoaf801632020-07-03 10:00:42 +0000307
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000308 return &dh
309}
310
Himani Chawla6d2ae152020-09-02 13:11:20 +0530311// start save the device to the data model
312func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000315 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000316}
317
Himani Chawla4d908332020-08-31 12:30:20 +0530318/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530320func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000321 logger.Debug("stopping-device-handler")
322 dh.exitChannel <- 1
323}
Himani Chawla4d908332020-08-31 12:30:20 +0530324*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000325
326// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530327// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328
Girish Gowdrae0140f02021-02-02 16:55:09 -0800329//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530330func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000331 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332
dbainbri4d3a0dc2020-12-02 00:33:42 +0000333 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000334 if dh.pDeviceStateFsm.Is(devStNull) {
335 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000337 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800339 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
340 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800341 // Now, set the initial PM configuration for that device
342 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
343 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
344 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800345 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000346 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000348 }
349
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000350}
351
mpagenko057889c2021-01-21 16:51:58 +0000352func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530353 msgBody := msg.GetBody()
354 omciMsg := &ic.InterAdapterOmciMessage{}
355 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530357 "device-id": dh.deviceID, "error": err})
358 return err
359 }
360
mpagenko80622a52021-02-09 16:53:23 +0000361 /* 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 +0530362 //assuming omci message content is hex coded!
363 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530365 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000366 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530368 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000369 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000370 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000371 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 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 +0530373 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000374 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530376}
377
Himani Chawla6d2ae152020-09-02 13:11:20 +0530378func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000379 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000381
dbainbri4d3a0dc2020-12-02 00:33:42 +0000382 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000383
dbainbri4d3a0dc2020-12-02 00:33:42 +0000384 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000385 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000386 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000387 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
388 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 if dh.pOnuTP == nil {
390 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000391 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530392 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000393 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530394 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000395 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000396 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000397 "device-state": dh.getDeviceReasonString()})
398 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530399 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000400 //previous state test here was just this one, now extended for more states to reject the SetRequest:
401 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
402 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530403
404 msgBody := msg.GetBody()
405 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
406 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530408 "device-id": dh.deviceID, "error": err})
409 return err
410 }
411
412 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000413 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
414 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530415 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000416 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000417
418 if techProfMsg.UniId > 255 {
419 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
420 techProfMsg.UniId, dh.deviceID))
421 }
422 uniID := uint8(techProfMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700423 tpID, err := GetTpIDFromTpPath(techProfMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800424 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700425 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.TpInstancePath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800426 return err
427 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700428 logger.Debugw(ctx, "unmarshal-techprof-msg-body", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000429
Girish Gowdra50e56422021-06-01 16:46:04 -0700430 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.TpInstancePath); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530431
Girish Gowdra50e56422021-06-01 16:46:04 -0700432 switch tpInst := techProfMsg.TechTpInstance.(type) {
433 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance:
434 logger.Debugw(ctx, "onu-uni-tp-path-modified", log.Fields{"uniID": uniID, "tp-path": techProfMsg.TpInstancePath, "tpID": tpID})
435 // if there has been some change for some uni TechProfilePath
436 //in order to allow concurrent calls to other dh instances we do not wait for execution here
437 //but doing so we can not indicate problems to the caller (who does what with that then?)
438 //by now we just assume straightforward successful execution
439 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
440 // possible problems to the caller later autonomously
Himani Chawla26e555c2020-08-31 12:30:20 +0530441
Girish Gowdra50e56422021-06-01 16:46:04 -0700442 // deadline context to ensure completion of background routines waited for
443 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
444 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
445 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000446
Girish Gowdra50e56422021-06-01 16:46:04 -0700447 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
448
449 var wg sync.WaitGroup
450 wg.Add(1) // for the 1 go routine to finish
451 // attention: deadline completion check and wg.Done is to be done in both routines
452 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.TpInstancePath, *tpInst.TpInstance, &wg)
453 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
454 if tpErr := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); tpErr != nil {
455 logger.Errorw(ctx, "error-processing-tp", log.Fields{"device-id": dh.deviceID, "err": tpErr, "tp-path": techProfMsg.TpInstancePath})
456 return tpErr
457 }
458 deadline = time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
459 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
460 pDevEntry.resetKvProcessingErrorIndication()
461 wg.Add(1) // for the 1 go routine to finish
462 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg)
463 dh.waitForCompletion(ctx, cancel2, &wg, "TechProfDwld") //wait for background process to finish
464 if kvErr := pDevEntry.getKvProcessingErrorIndication(); kvErr != nil {
465 logger.Errorw(ctx, "error-updating-KV", log.Fields{"device-id": dh.deviceID, "err": kvErr, "tp-path": techProfMsg.TpInstancePath})
466 return kvErr
467 }
468 return nil
469 default:
470 logger.Errorw(ctx, "unsupported-tp-instance-type", log.Fields{"tp-path": techProfMsg.TpInstancePath})
471 return fmt.Errorf("unsupported-tp-instance-type--tp-id-%v", techProfMsg.TpInstancePath)
Mahir Gunyel7f4483a2021-05-06 12:53:43 -0700472 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530473 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000474 // no change, nothing really to do - return success
Girish Gowdra50e56422021-06-01 16:46:04 -0700475 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 +0530476 return nil
477}
478
Himani Chawla6d2ae152020-09-02 13:11:20 +0530479func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530481 msg *ic.InterAdapterMessage) error {
482
483 if dh.pOnuTP == nil {
484 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000485 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530486 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530488 }
489
490 msgBody := msg.GetBody()
491 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
492 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530494 "device-id": dh.deviceID, "error": err})
495 return err
496 }
497
498 //compare TECH_PROFILE_DOWNLOAD_REQUEST
499 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530501
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000502 if delGemPortMsg.UniId > 255 {
503 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
504 delGemPortMsg.UniId, dh.deviceID))
505 }
506 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700507 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpInstancePath)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800508 if err != nil {
Girish Gowdra50e56422021-06-01 16:46:04 -0700509 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 -0800510 return err
511 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700512 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "gem": delGemPortMsg.GemPortId})
mpagenkofc4f56e2020-11-04 17:17:49 +0000513 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000514
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700515 return dh.deleteTechProfileResource(ctx, uniID, tpID, delGemPortMsg.TpInstancePath,
516 cResourceGemPort, delGemPortMsg.GemPortId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000517
Himani Chawla26e555c2020-08-31 12:30:20 +0530518}
519
Himani Chawla6d2ae152020-09-02 13:11:20 +0530520func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000521 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530522 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000523
dbainbri4d3a0dc2020-12-02 00:33:42 +0000524 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
528 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530529 if dh.pOnuTP == nil {
530 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000531 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530532 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000533 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530534 }
535
536 msgBody := msg.GetBody()
537 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
538 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530540 "device-id": dh.deviceID, "error": err})
541 return err
542 }
543
544 //compare TECH_PROFILE_DOWNLOAD_REQUEST
545 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000546 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000547
548 if delTcontMsg.UniId > 255 {
549 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
550 delTcontMsg.UniId, dh.deviceID))
551 }
552 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra50e56422021-06-01 16:46:04 -0700553 tpPath := delTcontMsg.TpInstancePath
Girish Gowdra041dcb32020-11-16 16:54:30 -0800554 tpID, err := GetTpIDFromTpPath(tpPath)
555 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000556 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800557 return err
558 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700559 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID, "tcont": delTcontMsg.AllocId})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000560
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700561 pDevEntry.freeTcont(ctx, uint16(delTcontMsg.AllocId))
Himani Chawla26e555c2020-08-31 12:30:20 +0530562
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700563 return dh.deleteTechProfileResource(ctx, uniID, tpID, delTcontMsg.TpInstancePath,
564 cResourceTcont, delTcontMsg.AllocId)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000565
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700566}
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000567
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700568func (dh *deviceHandler) deleteTechProfileResource(ctx context.Context,
569 uniID uint8, tpID uint8, pathString string, resource resourceEntry, entryID uint32) error {
570 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
571 if pDevEntry == nil {
572 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
573 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530574 }
Mahir Gunyel82b7f872021-07-04 15:53:16 -0700575 var resourceName string
576 if cResourceGemPort == resource {
577 resourceName = "Gem"
578 } else {
579 resourceName = "Tcont"
580 }
581
582 // deadline context to ensure completion of background routines waited for
583 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
584 dctx, cancel := context.WithDeadline(context.Background(), deadline)
585
586 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
587
588 var wg sync.WaitGroup
589 wg.Add(1) // for the 1 go routine to finish
590 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, pathString,
591 resource, entryID, &wg)
592 dh.waitForCompletion(ctx, cancel, &wg, resourceName+"Delete") //wait for background process to finish
593 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID); err != nil {
594 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
595 return err
596 }
597
598 if dh.pOnuTP.isTechProfileConfigCleared(ctx, uniID, tpID) {
599 logger.Debugw(ctx, "techProfile-config-cleared", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
600 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
601 pDevEntry.resetKvProcessingErrorIndication()
602 var wg2 sync.WaitGroup
603 dctx2, cancel2 := context.WithDeadline(context.Background(), deadline)
604 wg2.Add(1)
605 // Removal of the gem id mapping represents the removal of the tech profile
606 logger.Infow(ctx, "remove-techProfile-indication-in-kv", log.Fields{"device-id": dh.deviceID, "uni-id": uniID, "tpID": tpID})
607 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx2, ctx), &wg2)
608 dh.waitForCompletion(ctx, cancel2, &wg2, "TechProfileDeleteOn"+resourceName) //wait for background process to finish
609 if err := pDevEntry.getKvProcessingErrorIndication(); err != nil {
610 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
611 return err
612 }
613 }
614 }
615 logger.Debugw(ctx, "delete-tech-profile-resource-completed", log.Fields{"device-id": dh.deviceID,
616 "uni-id": uniID, "tpID": tpID, "resource-type": resourceName, "resource-id": entryID})
Himani Chawla26e555c2020-08-31 12:30:20 +0530617 return nil
618}
619
Himani Chawla6d2ae152020-09-02 13:11:20 +0530620//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000621// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
622// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000624 msgID := msg.Header.Id
625 msgType := msg.Header.Type
626 fromTopic := msg.Header.FromTopic
627 toTopic := msg.Header.ToTopic
628 toDeviceID := msg.Header.ToDeviceId
629 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000630 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000631 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
632
633 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000634 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000635 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
636 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000637 {
mpagenko057889c2021-01-21 16:51:58 +0000638 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000639 }
mpagenkoaf801632020-07-03 10:00:42 +0000640 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
641 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000643 }
644 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
645 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000647
mpagenkoaf801632020-07-03 10:00:42 +0000648 }
649 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
650 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000651 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000652 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000653 default:
654 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000656 "msgType": msg.Header.Type, "device-id": dh.deviceID})
657 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000658 }
659 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000660}
661
mpagenkodff5dda2020-08-28 11:52:01 +0000662//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
664 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000665 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300666 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID, "metadata": apFlowMetaData})
mpagenko01e726e2020-10-23 09:45:29 +0000667 var retError error = nil
668 //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 +0000669 if apOfFlowChanges.ToRemove != nil {
670 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000671 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000673 "device-id": dh.deviceID})
674 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000675 continue
676 }
677 flowInPort := flow.GetInPort(flowItem)
678 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000679 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 +0000680 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
681 continue
682 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000683 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000684 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000686 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000687 continue
688 } else {
689 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530690 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000691 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
692 loUniPort = uniPort
693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000694 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000695 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
696 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
697 flowInPort, dh.deviceID)
698 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000699 }
700 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000702 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000703 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000705 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000706 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000707 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000708 log.Fields{"device-id": dh.deviceID, "error": err})
709 retError = err
710 continue
711 //return err
712 } else { // if last setting succeeds, overwrite possibly previously set error
713 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000714 }
715 }
716 }
717 }
mpagenko01e726e2020-10-23 09:45:29 +0000718 if apOfFlowChanges.ToAdd != nil {
719 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
720 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000721 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000722 "device-id": dh.deviceID})
723 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
724 continue
725 }
726 flowInPort := flow.GetInPort(flowItem)
727 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728 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 +0000729 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
730 continue
731 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
732 } else if flowInPort == dh.ponPortNumber {
733 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000734 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000735 "device-id": dh.deviceID, "inPort": flowInPort})
736 continue
737 } else {
738 // this is the relevant upstream flow
739 var loUniPort *onuUniPort
740 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
741 loUniPort = uniPort
742 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000744 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
745 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
746 flowInPort, dh.deviceID)
747 continue
748 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
749 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000750 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
751 // if not, we just throw some error here to have an indication about that, if we really need to support that
752 // then we would need to create some means to activate the internal stored flows
753 // after the device gets active automatically (and still with its dependency to the TechProfile)
754 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
755 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000756 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000757 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000758 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000759 return fmt.Errorf("improper device state on device %s", dh.deviceID)
760 }
761
mpagenko01e726e2020-10-23 09:45:29 +0000762 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000763 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000764 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
765 "uniPortName": loUniPort.name})
ozgecanetsia82b91a62021-05-21 18:54:49 +0300766 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort, apFlowMetaData)
mpagenko01e726e2020-10-23 09:45:29 +0000767 //try next flow after processing error
768 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000769 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000770 log.Fields{"device-id": dh.deviceID, "error": err})
771 retError = err
772 continue
773 //return err
774 } else { // if last setting succeeds, overwrite possibly previously set error
775 retError = nil
776 }
777 }
778 }
779 }
780 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000781}
782
Himani Chawla6d2ae152020-09-02 13:11:20 +0530783//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000784//following are the expected device states after this activity:
785//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
786// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000787func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
788 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000789
mpagenko900ee4b2020-10-12 11:56:34 +0000790 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000791 //note that disableDevice sequences in some 'ONU active' state may yield also
792 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000793 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000794 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000795 //disable-device shall be just a UNi/ONU-G related admin state setting
796 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000797
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000798 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000799 // disable UNI ports/ONU
800 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
801 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000803 } else { //LockStateFSM already init
804 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000805 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000806 }
807 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000808 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000809 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000811 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
812 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000814 }
mpagenko01e726e2020-10-23 09:45:29 +0000815 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000816
817 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000819 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300820 }
821}
822
Himani Chawla6d2ae152020-09-02 13:11:20 +0530823//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000824func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
825 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000826
mpagenkoaa3afe92021-05-21 16:20:58 +0000827 //setting readyForOmciConfig here is just a workaround for BBSIM testing in the sequence
mpagenkofc4f56e2020-11-04 17:17:49 +0000828 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
829 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
830 // for real ONU's that should have nearly no influence
831 // Note that for real ONU's there is anyway a problematic situation with following sequence:
832 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
833 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
834 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000835 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000836
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000837 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000838 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000839 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000841 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000842 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000843 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000844 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300845}
846
dbainbri4d3a0dc2020-12-02 00:33:42 +0000847func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
848 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000849
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000851 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000852 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000853 return
854 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000855 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000856 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000857 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000858 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000860 }
Girish Gowdra50e56422021-06-01 16:46:04 -0700861 dh.stopReconciling(ctx, false)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000862 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000863 }
Himani Chawla4d908332020-08-31 12:30:20 +0530864 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000865 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000866 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
867 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
868 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
869 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000870 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000872}
873
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
875 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000876
dbainbri4d3a0dc2020-12-02 00:33:42 +0000877 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000878 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000879 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000880 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700881 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000882 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000883 return
884 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000885 dh.pOnuTP.lockTpProcMutex()
886 defer dh.pOnuTP.unlockTpProcMutex()
887
mpagenko5dc85a02021-08-02 12:35:01 +0000888 pDevEntry.mutexPersOnuConfig.RLock()
889 persMutexLock := true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000890 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +0000891 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000893 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000894 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700895 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000896 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000897 return
898 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899 flowsFound := false
Girish Gowdra50e56422021-06-01 16:46:04 -0700900 techProfsFound := false
901 techProfInstLoadFailed := false
902outerLoop:
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000903 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000904 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
905 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000906 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000907 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000909 }
mpagenko5dc85a02021-08-02 12:35:01 +0000910 //release mutexPersOnuConfig before TechProfile (ANIConfig) processing as otherwise the reception of
911 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
912 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
913 pDevEntry.mutexPersOnuConfig.RUnlock()
914 persMutexLock = false
Girish Gowdra50e56422021-06-01 16:46:04 -0700915 techProfsFound = true // set to true if we found TP once for any UNI port
Girish Gowdra041dcb32020-11-16 16:54:30 -0800916 for tpID := range uniData.PersTpPathMap {
Girish Gowdra50e56422021-06-01 16:46:04 -0700917 // Request the TpInstance again from the openolt adapter in case of reconcile
918 iaTechTpInst, err := dh.AdapterProxy.TechProfileInstanceRequest(ctx, uniData.PersTpPathMap[tpID],
919 dh.device.ParentPortNo, dh.device.ProxyAddress.OnuId, uint32(uniData.PersUniID),
920 dh.pOpenOnuAc.config.Topic, dh.ProxyAddressType,
921 dh.parentID, dh.ProxyAddressID)
922 if err != nil || iaTechTpInst == nil {
923 logger.Errorw(ctx, "error fetching tp instance",
924 log.Fields{"tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID, "err": err})
925 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
926 break outerLoop
927 }
928 var tpInst tech_profile.TechProfileInstance
929 switch techTpInst := iaTechTpInst.TechTpInstance.(type) {
930 case *ic.InterAdapterTechProfileDownloadMessage_TpInstance: // supports only GPON, XGPON, XGS-PON
931 tpInst = *techTpInst.TpInstance
mpagenko5dc85a02021-08-02 12:35:01 +0000932 logger.Debugw(ctx, "received-tp-instance-successfully-after-reconcile", log.Fields{
933 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700934 default: // do not support epon or other tech
mpagenko5dc85a02021-08-02 12:35:01 +0000935 logger.Errorw(ctx, "unsupported-tech-profile", log.Fields{
936 "tp-id": tpID, "tpPath": uniData.PersTpPathMap[tpID], "uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700937 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
938 break outerLoop
939 }
940
Girish Gowdra041dcb32020-11-16 16:54:30 -0800941 // deadline context to ensure completion of background routines waited for
942 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
943 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000945
Girish Gowdra041dcb32020-11-16 16:54:30 -0800946 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
947 var wg sync.WaitGroup
948 wg.Add(1) // for the 1 go routine to finish
Girish Gowdra50e56422021-06-01 16:46:04 -0700949 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], tpInst, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000950 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800951 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -0700953 techProfInstLoadFailed = true // stop loading tp instance as soon as we hit failure
954 break outerLoop
Girish Gowdra041dcb32020-11-16 16:54:30 -0800955 }
mpagenko5dc85a02021-08-02 12:35:01 +0000956 } // for all TpPath entries for this UNI
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 if len(uniData.PersFlowParams) != 0 {
958 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000959 }
mpagenko5dc85a02021-08-02 12:35:01 +0000960 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
961 persMutexLock = true
962 } // for all UNI entries from sOnuPersistentData
963 if persMutexLock { // if loop was left with mutexPersOnuConfig still set
964 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000965 }
mpagenko5dc85a02021-08-02 12:35:01 +0000966
967 //had to move techProf/flow result evaluation into separate function due to SCA complexity limit
968 dh.updateReconcileStates(ctx, techProfsFound, techProfInstLoadFailed, flowsFound)
969}
970
971func (dh *deviceHandler) updateReconcileStates(ctx context.Context,
972 abTechProfsFound bool, abTechProfInstLoadFailed bool, abFlowsFound bool) {
973 if !abTechProfsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000974 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
975 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000976 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700977 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000978 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000979 return
980 }
mpagenko5dc85a02021-08-02 12:35:01 +0000981 if abTechProfInstLoadFailed {
Girish Gowdra50e56422021-06-01 16:46:04 -0700982 dh.setDeviceReason(drTechProfileConfigDownloadFailed)
983 dh.stopReconciling(ctx, false)
984 return
985 } else if dh.isSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000986 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
987 }
mpagenko5dc85a02021-08-02 12:35:01 +0000988 if !abFlowsFound {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000989 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
990 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000991 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -0700992 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000993 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000994 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000995}
996
dbainbri4d3a0dc2020-12-02 00:33:42 +0000997func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
998 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000999
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001002 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001003 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001004 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001005 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001006 return
1007 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001008
mpagenko5dc85a02021-08-02 12:35:01 +00001009 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001010 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
mpagenko5dc85a02021-08-02 12:35:01 +00001011 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001012 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001013 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001014 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001015 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001016 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001017 return
1018 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001019 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001020 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001021 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
1022 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001023 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001024 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001025 continue
1026 }
1027 if len(uniData.PersTpPathMap) == 0 {
1028 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
1029 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001030 // It doesn't make sense to configure any flows if no TPs are available
1031 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001032 }
mpagenko5dc85a02021-08-02 12:35:01 +00001033 //release mutexPersOnuConfig before VlanConfig processing as otherwise the reception of
1034 // OMCI frames may get completely stuck due to lock request within incrementMibDataSync() at OMCI
1035 // frame reception may also lock the complete OMCI reception processing based on mutexRxSchedMap
1036 pDevEntry.mutexPersOnuConfig.RUnlock()
1037
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001038 var uniPort *onuUniPort
1039 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +00001040 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001041 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001042 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
1043 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001044 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001045 dh.stopReconciling(ctx, false)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001046 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001047 return
1048 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001049 flowsFound = true
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001050 lastFlowToReconcile := false
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001051 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001052 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001053 for _, flowData := range uniData.PersFlowParams {
mpagenko5dc85a02021-08-02 12:35:01 +00001054 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{
1055 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "cookies": flowData.CookieSlice})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001056 // If this is the last flow for the device we need to announce it the waiting
1057 // chReconcilingFlowsFinished channel
1058 if flowsProcessed == len(uniData.PersFlowParams)-1 {
1059 lastFlowToReconcile = true
1060 }
mpagenko01e726e2020-10-23 09:45:29 +00001061 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenko37047052021-07-27 10:01:29 +00001062 dh.lockVlanConfig.Lock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001063 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001064 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +00001065 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001066 uint8(flowData.VlanRuleParams.SetPcp), lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001067 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001068 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001069 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00001071 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
ozgecanetsia82b91a62021-05-21 18:54:49 +03001072 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone, lastFlowToReconcile, flowData.Meter); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001074 }
1075 }
mpagenko37047052021-07-27 10:01:29 +00001076 dh.lockVlanConfig.Unlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001077 flowsProcessed++
mpagenko5dc85a02021-08-02 12:35:01 +00001078 } //for all flows of this UNI
1079 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{
1080 "device-id": dh.deviceID, "uni-id": uniData.PersUniID, "flowsProcessed": flowsProcessed,
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001081 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
1082 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001083 // this can't be used as global finished reconciling flag because
1084 // assumes is getting called before the state machines for the last flow is completed,
1085 // while this is not guaranteed.
1086 //dh.setReconcilingFlows(false)
mpagenko5dc85a02021-08-02 12:35:01 +00001087 pDevEntry.mutexPersOnuConfig.RLock() //set protection again for loop test on sOnuPersistentData
1088 } // for all UNI entries from sOnuPersistentData
1089 pDevEntry.mutexPersOnuConfig.RUnlock()
1090
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001091 if !flowsFound {
1092 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
1093 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001094 if !dh.isSkipOnuConfigReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07001095 dh.stopReconciling(ctx, true)
Holger Hildebrandt7e9de862021-03-26 14:01:49 +00001096 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001097 return
1098 }
1099 if dh.isSkipOnuConfigReconciling() {
1100 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001101 }
1102}
1103
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001104func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
1105 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001106 dh.stopReconciling(ctx, true)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001107}
1108
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
1110 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001111
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001113 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +00001114 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001116 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001117 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001118
1119 // deadline context to ensure completion of background routines waited for
1120 //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 +05301121 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001123
1124 pDevEntry.resetKvProcessingErrorIndication()
1125
1126 var wg sync.WaitGroup
1127 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001128 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1129 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001130
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001131 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001132 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001133}
1134
mpagenko15ff4a52021-03-02 10:09:20 +00001135//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1136// before this change here return like this was used:
1137// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1138//was and is called in background - error return does not make sense
1139func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1140 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1141 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001142 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001143 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001144 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301146 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001148 return
Himani Chawla4d908332020-08-31 12:30:20 +05301149 }
mpagenko01e726e2020-10-23 09:45:29 +00001150
1151 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001153
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001155 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001156 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001157 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001158 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001159 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001160 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001161 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001162 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001163 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001164 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001165 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001166 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1167 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1168 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1169 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001170}
1171
mpagenkoc8bba412021-01-15 15:38:44 +00001172//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko9c225032021-10-15 14:26:49 +00001173// used only for old - R2.7 style - upgrade API
mpagenko80622a52021-02-09 16:53:23 +00001174func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1175 apDownloadManager *adapterDownloadManager) error {
1176 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001177 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001178
1179 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001180 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1181 if pDevEntry == nil {
1182 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1183 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1184 }
1185
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001186 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001187 var inactiveImageID uint16
1188 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1189 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001190 //lockUpgradeFsm must be release before cancelation as this may implicitly request RemoveOnuUpgradeFsm()
1191 // but must be still locked at calling createOnuUpgradeFsm
mpagenko15ff4a52021-03-02 10:09:20 +00001192 if dh.pOnuUpradeFsm == nil {
1193 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001194 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001195 if err == nil {
1196 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1197 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1198 "device-id": dh.deviceID, "error": err})
1199 }
1200 } else {
1201 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001202 "device-id": dh.deviceID, "error": err})
1203 }
mpagenko15ff4a52021-03-02 10:09:20 +00001204 } else { //OnuSw upgrade already running - restart (with possible abort of running)
mpagenko9c225032021-10-15 14:26:49 +00001205 dh.lockUpgradeFsm.Unlock()
mpagenko15ff4a52021-03-02 10:09:20 +00001206 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00001207 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1208 dh.upgradeCanceled = true
1209 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
mpagenko80622a52021-02-09 16:53:23 +00001210 }
mpagenko9c225032021-10-15 14:26:49 +00001211 //no effort spent anymore for the old API to automatically cancel and restart the download
1212 // like done for the new API
mpagenko80622a52021-02-09 16:53:23 +00001213 }
mpagenko15ff4a52021-03-02 10:09:20 +00001214 } else {
1215 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1216 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001217 }
1218 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001219 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1220 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001221 }
1222 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001223}
1224
mpagenkoc26d4c02021-05-06 14:27:57 +00001225//onuSwUpgradeAfterDownload initiates the SW download transfer to the ONU with activate and commit options
1226// after the OnuImage has been downloaded to the adapter, called in background
1227func (dh *deviceHandler) onuSwUpgradeAfterDownload(ctx context.Context, apImageRequest *voltha.DeviceImageDownloadRequest,
1228 apDownloadManager *fileDownloadManager, aImageIdentifier string) {
1229
1230 var err error
1231 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1232 if pDevEntry == nil {
1233 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1234 return
1235 }
1236
1237 var inactiveImageID uint16
1238 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1239 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
1240 "device-id": dh.deviceID, "image-version": apImageRequest.Image.Version, "to onu-image": inactiveImageID})
1241 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00001242 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
1243 // but must be still locked at calling createOnuUpgradeFsm
1244 // (and working with a local pointer copy does not work here if asynchronous request are done to fast
1245 // [e.g.leaving the local pointer on nil even though a creation is already on the way])
1246 if dh.pOnuUpradeFsm != nil {
1247 //OnuSw upgrade already running on this device (e.g. with activate/commit not yet set)
1248 // abort the current processing, running upgrades are always aborted by newer request
1249 logger.Debugw(ctx, "Onu SW upgrade already running - abort previous activity", log.Fields{"device-id": dh.deviceID})
1250 //flush the remove upgradeFsmChan channel
1251 select {
1252 case <-dh.upgradeFsmChan:
1253 logger.Debug(ctx, "flushed-upgrade-fsm-channel")
1254 default:
mpagenkoc26d4c02021-05-06 14:27:57 +00001255 }
mpagenko9c225032021-10-15 14:26:49 +00001256 dh.lockUpgradeFsm.Unlock()
1257 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1258 dh.upgradeCanceled = true
1259 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1260 }
1261 select {
1262 case <-time.After(cTimeOutRemoveUpgrade * time.Second):
1263 logger.Errorw(ctx, "could not remove Upgrade FSM in time, aborting", log.Fields{"device-id": dh.deviceID})
1264 //should not appear, can't proceed with new upgrade, perhaps operator can retry manually later
1265 return
1266 case <-dh.upgradeFsmChan:
1267 logger.Debugw(ctx, "recent Upgrade FSM removed, proceed with new request", log.Fields{"device-id": dh.deviceID})
1268 }
1269 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001270 }
mpagenko9c225032021-10-15 14:26:49 +00001271
1272 //here it can be assumed that no running upgrade processing exists (anymore)
1273 //OmciOnuSwUpgradeDone could be used to create some event notification with information on upgrade completion,
1274 // but none yet defined
1275 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1276 dh.lockUpgradeFsm.Unlock()
1277 if err == nil {
1278 if err = dh.pOnuUpradeFsm.SetDownloadParamsAfterDownload(ctx, inactiveImageID,
1279 apImageRequest, apDownloadManager, aImageIdentifier); err != nil {
1280 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
mpagenkoc26d4c02021-05-06 14:27:57 +00001281 "device-id": dh.deviceID, "error": err})
1282 return
1283 }
mpagenko9c225032021-10-15 14:26:49 +00001284 } else {
1285 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1286 "device-id": dh.deviceID, "error": err})
mpagenkoc26d4c02021-05-06 14:27:57 +00001287 }
1288 return
1289 }
1290 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1291 "device-id": dh.deviceID, "error": err})
1292}
1293
1294//onuSwActivateRequest ensures activation of the requested image with commit options
mpagenko183647c2021-06-08 15:25:04 +00001295func (dh *deviceHandler) onuSwActivateRequest(ctx context.Context,
1296 aVersion string, aCommitRequest bool) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001297 var err error
1298 //SW activation for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1299 // 1.) activation of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1300 // 2.) activation of the inactive image
1301
1302 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1303 if pDevEntry == nil {
1304 logger.Errorw(ctx, "Onu image activation rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001305 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001306 }
1307 dh.lockUpgradeFsm.RLock()
1308 if dh.pOnuUpradeFsm != nil {
1309 dh.lockUpgradeFsm.RUnlock()
1310 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1311 dh.deviceID, dh.deviceID)
1312 if getErr != nil || onuVolthaDevice == nil {
1313 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 +00001314 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001315 }
mpagenko9c225032021-10-15 14:26:49 +00001316 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1317 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1318 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1319 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001320 // use the OnuVendor identification from this device for the internal unique name
1321 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001322 // 1.) check a started upgrade process and relay the activation request to it
mpagenkoc26d4c02021-05-06 14:27:57 +00001323 if err = dh.pOnuUpradeFsm.SetActivationParamsRunning(ctx, imageIdentifier, aCommitRequest); err != nil {
mpagenko183647c2021-06-08 15:25:04 +00001324 //if some ONU upgrade is ongoing we do not accept some explicit ONU image-version related activation
mpagenkoc26d4c02021-05-06 14:27:57 +00001325 logger.Errorw(ctx, "onu upgrade fsm did not accept activation while running", log.Fields{
1326 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001327 return nil, fmt.Errorf("activation not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001328 }
mpagenko183647c2021-06-08 15:25:04 +00001329 logger.Debugw(ctx, "image activation acknowledged by onu upgrade processing", log.Fields{
1330 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001331 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001332 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001333 } //else
1334 dh.lockUpgradeFsm.RUnlock()
1335
1336 // 2.) check if requested image-version equals the inactive one and start its activation
1337 // (image version is not [yet] checked - would be possible, but with increased effort ...)
1338 var inactiveImageID uint16
1339 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err != nil || inactiveImageID > 1 {
1340 logger.Errorw(ctx, "get inactive image failed", log.Fields{
1341 "device-id": dh.deviceID, "err": err, "image-id": inactiveImageID})
mpagenko183647c2021-06-08 15:25:04 +00001342 return nil, fmt.Errorf("no valid inactive image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001343 }
mpagenko9c225032021-10-15 14:26:49 +00001344 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001345 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001346 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001347 if err == nil {
1348 if err = dh.pOnuUpradeFsm.SetActivationParamsStart(ctx, aVersion,
1349 inactiveImageID, aCommitRequest); err != nil {
1350 logger.Errorw(ctx, "onu upgrade fsm did not accept activation to start", log.Fields{
1351 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001352 return nil, fmt.Errorf("activation to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001353 }
1354 logger.Debugw(ctx, "inactive image activation acknowledged by onu upgrade", log.Fields{
1355 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001356 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001357 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001358 } //else
1359 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1360 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001361 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001362}
1363
1364//onuSwCommitRequest ensures commitment of the requested image
mpagenko183647c2021-06-08 15:25:04 +00001365func (dh *deviceHandler) onuSwCommitRequest(ctx context.Context,
1366 aVersion string) (*voltha.ImageState, error) {
mpagenkoc26d4c02021-05-06 14:27:57 +00001367 var err error
1368 //SW commitment for the ONU image may have two use cases, one of them is selected here according to following prioritization:
1369 // 1.) commitment of the image for a started upgrade process (in case the running upgrade runs on the requested image)
1370 // 2.) commitment of the active image
1371
1372 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1373 if pDevEntry == nil {
1374 logger.Errorw(ctx, "Onu image commitment rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
mpagenko183647c2021-06-08 15:25:04 +00001375 return nil, fmt.Errorf("no valid OnuDevice for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001376 }
1377 dh.lockUpgradeFsm.RLock()
1378 if dh.pOnuUpradeFsm != nil {
1379 dh.lockUpgradeFsm.RUnlock()
1380 onuVolthaDevice, getErr := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx),
1381 dh.deviceID, dh.deviceID)
1382 if getErr != nil || onuVolthaDevice == nil {
1383 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 +00001384 return nil, fmt.Errorf("could not fetch device for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001385 }
mpagenko9c225032021-10-15 14:26:49 +00001386 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
1387 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
1388 return nil, fmt.Errorf("request collides with some ongoing cancelation for device-id: %s", dh.deviceID)
1389 }
mpagenkoc26d4c02021-05-06 14:27:57 +00001390 // use the OnuVendor identification from this device for the internal unique name
1391 imageIdentifier := onuVolthaDevice.VendorId + aVersion //head on vendor ID of the ONU
mpagenko9c225032021-10-15 14:26:49 +00001392 // 1.) check a started upgrade process and relay the commitment request to it
1393 // the running upgrade may be based either on the imageIdentifier (started from download)
1394 // or on the imageVersion (started from pure activation)
1395 if err = dh.pOnuUpradeFsm.SetCommitmentParamsRunning(ctx, imageIdentifier, aVersion); err != nil {
1396 //if some ONU upgrade is ongoing we do not accept some explicit different ONU image-version related commitment
mpagenkoc26d4c02021-05-06 14:27:57 +00001397 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment while running", log.Fields{
1398 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001399 return nil, fmt.Errorf("commitment not accepted for this version for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001400 }
mpagenko183647c2021-06-08 15:25:04 +00001401 logger.Debugw(ctx, "image commitment acknowledged by onu upgrade processing", log.Fields{
1402 "device-id": dh.deviceID, "image-id": imageIdentifier})
mpagenko9c225032021-10-15 14:26:49 +00001403 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001404 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001405 } //else
1406 dh.lockUpgradeFsm.RUnlock()
1407
mpagenko183647c2021-06-08 15:25:04 +00001408 // 2.) use the active image to directly commit
mpagenkoc26d4c02021-05-06 14:27:57 +00001409 var activeImageID uint16
1410 if activeImageID, err = pDevEntry.GetActiveImageMeID(ctx); err != nil || activeImageID > 1 {
1411 logger.Errorw(ctx, "get active image failed", log.Fields{
1412 "device-id": dh.deviceID, "err": err, "image-id": activeImageID})
mpagenko183647c2021-06-08 15:25:04 +00001413 return nil, fmt.Errorf("no valid active image found for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001414 }
mpagenko9c225032021-10-15 14:26:49 +00001415 dh.lockUpgradeFsm.Lock() //lock again for following creation
mpagenkoc26d4c02021-05-06 14:27:57 +00001416 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
mpagenko9c225032021-10-15 14:26:49 +00001417 dh.lockUpgradeFsm.Unlock()
mpagenkoc26d4c02021-05-06 14:27:57 +00001418 if err == nil {
1419 if err = dh.pOnuUpradeFsm.SetCommitmentParamsStart(ctx, aVersion, activeImageID); err != nil {
1420 logger.Errorw(ctx, "onu upgrade fsm did not accept commitment to start", log.Fields{
1421 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001422 return nil, fmt.Errorf("commitment to start from scratch not accepted for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001423 }
1424 logger.Debugw(ctx, "active image commitment acknowledged by onu upgrade", log.Fields{
1425 "device-id": dh.deviceID, "image-version": aVersion})
mpagenko9c225032021-10-15 14:26:49 +00001426 pImageStates := dh.pOnuUpradeFsm.GetImageStates(ctx, "", aVersion)
mpagenko183647c2021-06-08 15:25:04 +00001427 return pImageStates, nil
mpagenkoc26d4c02021-05-06 14:27:57 +00001428 } //else
1429 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
1430 "device-id": dh.deviceID, "error": err})
mpagenko183647c2021-06-08 15:25:04 +00001431 return nil, fmt.Errorf("could not start upgradeFsm for device-id: %s", dh.deviceID)
mpagenkoc26d4c02021-05-06 14:27:57 +00001432}
1433
mpagenkoaa3afe92021-05-21 16:20:58 +00001434func (dh *deviceHandler) requestOnuSwUpgradeState(ctx context.Context, aImageIdentifier string,
mpagenko9c225032021-10-15 14:26:49 +00001435 aVersion string) *voltha.ImageState {
1436 var pImageState *voltha.ImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001437 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00001438 defer dh.lockUpgradeFsm.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00001439 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001440 pImageState = dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
1441 } else { //use the last stored ImageState (if the requested Imageversion coincides)
1442 if aVersion == dh.pLastUpgradeImageState.Version {
1443 pImageState = dh.pLastUpgradeImageState
1444 } else { //state request for an image version different from last processed image version
1445 pImageState = &voltha.ImageState{
1446 Version: aVersion,
1447 //we cannot state something concerning this version
1448 DownloadState: voltha.ImageState_DOWNLOAD_UNKNOWN,
1449 Reason: voltha.ImageState_NO_ERROR,
1450 ImageState: voltha.ImageState_IMAGE_UNKNOWN,
1451 }
mpagenkoaa3afe92021-05-21 16:20:58 +00001452 }
1453 }
mpagenko9c225032021-10-15 14:26:49 +00001454 return pImageState
mpagenkoaa3afe92021-05-21 16:20:58 +00001455}
1456
1457func (dh *deviceHandler) cancelOnuSwUpgrade(ctx context.Context, aImageIdentifier string,
1458 aVersion string, pDeviceImageState *voltha.DeviceImageState) {
1459 pDeviceImageState.DeviceId = dh.deviceID
mpagenko7455fd42021-06-10 16:25:55 +00001460 pDeviceImageState.ImageState.Version = aVersion
mpagenkoaa3afe92021-05-21 16:20:58 +00001461 dh.lockUpgradeFsm.RLock()
1462 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00001463 // so then we cancel the upgrade operation
1464 // but before we still request the actual upgrade states for the direct response
1465 pImageState := dh.pOnuUpradeFsm.GetImageStates(ctx, aImageIdentifier, aVersion)
mpagenkoaa3afe92021-05-21 16:20:58 +00001466 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001467 pDeviceImageState.ImageState.DownloadState = pImageState.DownloadState
mpagenkoaa3afe92021-05-21 16:20:58 +00001468 pDeviceImageState.ImageState.Reason = voltha.ImageState_CANCELLED_ON_REQUEST
mpagenko9c225032021-10-15 14:26:49 +00001469 pDeviceImageState.ImageState.ImageState = pImageState.ImageState
1470 if pImageState.DownloadState != voltha.ImageState_DOWNLOAD_UNKNOWN {
1471 //so here the imageIdentifier or version equals to what is used in the upgrade FSM
1472 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
1473 dh.upgradeCanceled = true
1474 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_REQUEST) //complete abort
1475 }
1476 } //nothing to cancel (upgrade FSM for different image stays alive)
mpagenkoaa3afe92021-05-21 16:20:58 +00001477 } else {
1478 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00001479 // if no upgrade is ongoing, nothing is canceled and accordingly the states of the requested image are unknown
1480 // reset also the dh handler LastUpgradeImageState (not relevant anymore/cleared)
1481 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1482 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
1483 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
1484 (*dh.pLastUpgradeImageState).Version = "" //reset to 'no (relevant) upgrade done' (like initial state)
mpagenkoaa3afe92021-05-21 16:20:58 +00001485 pDeviceImageState.ImageState.DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
1486 pDeviceImageState.ImageState.Reason = voltha.ImageState_NO_ERROR
mpagenko9c225032021-10-15 14:26:49 +00001487 pDeviceImageState.ImageState.ImageState = voltha.ImageState_IMAGE_UNKNOWN
1488 //an abort request to a not active upgrade processing can be used to reset the device upgrade states completely
mpagenkoaa3afe92021-05-21 16:20:58 +00001489 }
1490}
1491
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00001492func (dh *deviceHandler) getOnuImages(ctx context.Context) (*voltha.OnuImages, error) {
1493
1494 var onuImageStatus *OnuImageStatus
1495
1496 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1497 if pDevEntry != nil {
1498 onuImageStatus = NewOnuImageStatus(pDevEntry)
1499 pDevEntry.mutexOnuImageStatus.Lock()
1500 pDevEntry.pOnuImageStatus = onuImageStatus
1501 pDevEntry.mutexOnuImageStatus.Unlock()
1502
1503 } else {
1504 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1505 return nil, fmt.Errorf("no-valid-OnuDevice-aborting")
1506 }
1507 images, err := onuImageStatus.getOnuImageStatus(ctx)
1508 pDevEntry.mutexOnuImageStatus.Lock()
1509 pDevEntry.pOnuImageStatus = nil
1510 pDevEntry.mutexOnuImageStatus.Unlock()
1511 return images, err
1512}
1513
Himani Chawla6d2ae152020-09-02 13:11:20 +05301514// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001515// #####################################################################################
1516
1517// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301518// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001519
dbainbri4d3a0dc2020-12-02 00:33:42 +00001520func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1521 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 +00001522}
1523
1524// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001525func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001526
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001528 var err error
1529
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001530 // populate what we know. rest comes later after mib sync
1531 dh.device.Root = false
1532 dh.device.Vendor = "OpenONU"
1533 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001534 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001535 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001536
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001537 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001538
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001539 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1541 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301542 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001543 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001544 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001545 log.Fields{"device-id": dh.deviceID})
1546 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001547
Himani Chawla4d908332020-08-31 12:30:20 +05301548 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001549 dh.ponPortNumber = dh.device.ParentPortNo
1550
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001551 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1552 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1553 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001555 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301556 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001557
1558 /*
1559 self._pon = PonPort.create(self, self._pon_port_number)
1560 self._pon.add_peer(self.parent_id, self._pon_port_number)
1561 self.logger.debug('adding-pon-port-to-agent',
1562 type=self._pon.get_port().type,
1563 admin_state=self._pon.get_port().admin_state,
1564 oper_status=self._pon.get_port().oper_status,
1565 )
1566 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001567 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001569 var ponPortNo uint32 = 1
1570 if dh.ponPortNumber != 0 {
1571 ponPortNo = dh.ponPortNumber
1572 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001574 pPonPort := &voltha.Port{
1575 PortNo: ponPortNo,
1576 Label: fmt.Sprintf("pon-%d", ponPortNo),
1577 Type: voltha.Port_PON_ONU,
1578 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301579 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001580 PortNo: ponPortNo}}, // Peer port is parent's port number
1581 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1583 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001584 e.Cancel(err)
1585 return
1586 }
1587 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001591}
1592
1593// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001595
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001597 var err error
1598 /*
1599 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1600 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1601 return nil
1602 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1604 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001605 e.Cancel(err)
1606 return
1607 }
1608
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001609 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001610 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001611 // reconcilement will be continued after mib download is done
1612 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001613
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001614 /*
1615 ############################################################################
1616 # Setup Alarm handler
1617 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1618 device.serial_number)
1619 ############################################################################
1620 # Setup PM configuration for this device
1621 # Pass in ONU specific options
1622 kwargs = {
1623 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1624 'heartbeat': self.heartbeat,
1625 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1626 }
1627 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1628 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1629 self.logical_device_id, device.serial_number,
1630 grouped=True, freq_override=False, **kwargs)
1631 pm_config = self._pm_metrics.make_proto()
1632 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1633 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1634 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1635
1636 # Note, ONU ID and UNI intf set in add_uni_port method
1637 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1638 ani_ports=[self._pon])
1639
1640 # Code to Run OMCI Test Action
1641 kwargs_omci_test_action = {
1642 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1643 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1644 }
1645 serial_number = device.serial_number
1646 self._test_request = OmciTestRequest(self.core_proxy,
1647 self.omci_agent, self.device_id,
1648 AniG, serial_number,
1649 self.logical_device_id,
1650 exclusive=False,
1651 **kwargs_omci_test_action)
1652
1653 self.enabled = True
1654 else:
1655 self.logger.info('onu-already-activated')
1656 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001657
dbainbri4d3a0dc2020-12-02 00:33:42 +00001658 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001659}
1660
1661// doStateConnected get the device info and update to voltha core
1662// for comparison of the original method (not that easy to uncomment): compare here:
1663// voltha-openolt-adapter/adaptercore/device_handler.go
1664// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001666
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301668 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001669 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001671}
1672
1673// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001675
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301677 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001678 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001680
1681 /*
1682 // Synchronous call to update device state - this method is run in its own go routine
1683 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1684 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001685 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 +00001686 return err
1687 }
1688 return nil
1689 */
1690}
1691
1692// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001694
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001696 var err error
1697
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001698 device := dh.device
1699 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001700 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001702 e.Cancel(err)
1703 return
1704 }
1705
1706 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001707 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001708 /*
1709 // Update the all ports state on that device to disable
1710 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001711 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001712 return er
1713 }
1714
1715 //Update the device oper state and connection status
1716 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1717 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1718 dh.device = cloned
1719
1720 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001721 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001722 return er
1723 }
1724
1725 //get the child device for the parent device
1726 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1727 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001728 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001729 return err
1730 }
1731 for _, onuDevice := range onuDevices.Items {
1732
1733 // Update onu state as down in onu adapter
1734 onuInd := oop.OnuIndication{}
1735 onuInd.OperState = "down"
1736 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1737 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1738 if er != nil {
1739 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001740 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001741 //Do not return here and continue to process other ONUs
1742 }
1743 }
1744 // * Discovered ONUs entries need to be cleared , since after OLT
1745 // is up, it starts sending discovery indications again* /
1746 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001747 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001748 return nil
1749 */
Himani Chawla4d908332020-08-31 12:30:20 +05301750 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001751 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001752 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001753}
1754
Himani Chawla6d2ae152020-09-02 13:11:20 +05301755// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001756// #################################################################################
1757
1758// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301759// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001760
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001761//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001763 dh.lockDevice.RLock()
1764 pOnuDeviceEntry := dh.pOnuOmciDevice
1765 if aWait && pOnuDeviceEntry == nil {
1766 //keep the read sema short to allow for subsequent write
1767 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001768 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001769 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1770 // so it might be needed to wait here for that event with some timeout
1771 select {
1772 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001774 return nil
1775 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001776 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001777 // if written now, we can return the written value without sema
1778 return dh.pOnuOmciDevice
1779 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001780 }
mpagenko3af1f032020-06-10 08:53:41 +00001781 dh.lockDevice.RUnlock()
1782 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001783}
1784
Himani Chawla6d2ae152020-09-02 13:11:20 +05301785//setOnuDeviceEntry sets the ONU device entry within the handler
1786func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001787 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001788 dh.lockDevice.Lock()
1789 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001790 dh.pOnuOmciDevice = apDeviceEntry
1791 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001792 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301793 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001794 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001795}
1796
Himani Chawla6d2ae152020-09-02 13:11:20 +05301797//addOnuDeviceEntry creates a new ONU device or returns the existing
1798func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001800
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001802 if deviceEntry == nil {
1803 /* costum_me_map in python code seems always to be None,
1804 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1805 /* also no 'clock' argument - usage open ...*/
1806 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001807 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001808 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001809 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301810 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001811 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001812 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001813 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001814 // fire deviceEntry ready event to spread to possibly waiting processing
1815 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001816 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001817 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001819 }
1820 // might be updated with some error handling !!!
1821 return nil
1822}
1823
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1825 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001826 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1827
1828 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001829
dbainbri4d3a0dc2020-12-02 00:33:42 +00001830 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001831 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001833 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1834 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001835 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 if err := dh.storePersistentData(ctx); err != nil {
1837 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001838 log.Fields{"device-id": dh.deviceID, "err": err})
1839 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001841 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001843 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1844 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001846 }
1847 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001849 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001850
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001851 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001852 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001853 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 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 +00001855 log.Fields{"device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07001856 dh.stopReconciling(ctx, true)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001857 } else {
1858 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001859 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001860 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001861 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1862 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1863 // 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 +00001864 // 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 +00001865 // so let's just try to keep it simple ...
1866 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001868 if err != nil || device == nil {
1869 //TODO: needs to handle error scenarios
1870 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1871 return errors.New("Voltha Device not found")
1872 }
1873 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001874
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001876 return err
mpagenko3af1f032020-06-10 08:53:41 +00001877 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001878
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001879 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001880
1881 /* this might be a good time for Omci Verify message? */
1882 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001884 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001885 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001886 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001887
1888 /* give the handler some time here to wait for the OMCi verification result
1889 after Timeout start and try MibUpload FSM anyway
1890 (to prevent stopping on just not supported OMCI verification from ONU) */
1891 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001892 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001894 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001896 }
1897
1898 /* In py code it looks earlier (on activate ..)
1899 # Code to Run OMCI Test Action
1900 kwargs_omci_test_action = {
1901 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1902 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1903 }
1904 serial_number = device.serial_number
1905 self._test_request = OmciTestRequest(self.core_proxy,
1906 self.omci_agent, self.device_id,
1907 AniG, serial_number,
1908 self.logical_device_id,
1909 exclusive=False,
1910 **kwargs_omci_test_action)
1911 ...
1912 # Start test requests after a brief pause
1913 if not self._test_request_started:
1914 self._test_request_started = True
1915 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1916 reactor.callLater(tststart, self._test_request.start_collector)
1917
1918 */
1919 /* which is then: in omci_test_request.py : */
1920 /*
1921 def start_collector(self, callback=None):
1922 """
1923 Start the collection loop for an adapter if the frequency > 0
1924
1925 :param callback: (callable) Function to call to collect PM data
1926 """
1927 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1928 if callback is None:
1929 callback = self.perform_test_omci
1930
1931 if self.lc is None:
1932 self.lc = LoopingCall(callback)
1933
1934 if self.default_freq > 0:
1935 self.lc.start(interval=self.default_freq / 10)
1936
1937 def perform_test_omci(self):
1938 """
1939 Perform the initial test request
1940 """
1941 ani_g_entities = self._device.configuration.ani_g_entities
1942 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1943 is not None else None
1944 self._entity_id = ani_g_entities_ids[0]
1945 self.logger.info('perform-test', entity_class=self._entity_class,
1946 entity_id=self._entity_id)
1947 try:
1948 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1949 result = yield self._device.omci_cc.send(frame)
1950 if not result.fields['omci_message'].fields['success_code']:
1951 self.logger.info('Self-Test Submitted Successfully',
1952 code=result.fields[
1953 'omci_message'].fields['success_code'])
1954 else:
1955 raise TestFailure('Test Failure: {}'.format(
1956 result.fields['omci_message'].fields['success_code']))
1957 except TimeoutError as e:
1958 self.deferred.errback(failure.Failure(e))
1959
1960 except Exception as e:
1961 self.logger.exception('perform-test-Error', e=e,
1962 class_id=self._entity_class,
1963 entity_id=self._entity_id)
1964 self.deferred.errback(failure.Failure(e))
1965
1966 */
1967
1968 // PM related heartbeat??? !!!TODO....
1969 //self._heartbeat.enabled = True
1970
mpagenko1cc3cb42020-07-27 15:24:38 +00001971 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1972 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1973 * 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 +05301974 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001975 */
1976 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001977 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001978 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001979 if pMibUlFsm.Is(ulStDisabled) {
1980 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 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 +00001982 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301983 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301985 //Determine ONU status and start/re-start MIB Synchronization tasks
1986 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001987 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301988 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 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 +00001990 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001991 }
Himani Chawla4d908332020-08-31 12:30:20 +05301992 } else {
1993 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 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 +00001995 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301996 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001998 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001999 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002001 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002002 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002003 }
2004 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002006 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002007 }
2008 return nil
2009}
2010
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00002012 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00002013 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002014 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00002016
mpagenko900ee4b2020-10-12 11:56:34 +00002017 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
2018 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
2019 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002020 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00002022 log.Fields{"device-id": dh.deviceID, "error": err})
2023 // abort: system behavior is just unstable ...
2024 return err
2025 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002026 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 _ = 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 +00002028
2029 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
2030 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
2031 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00002032 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00002033 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002034 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002035 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00002036 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002037 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00002038
2039 //TODO!!! remove existing traffic profiles
2040 /* from py code, if TP's exist, remove them - not yet implemented
2041 self._tp = dict()
2042 # Let TP download happen again
2043 for uni_id in self._tp_service_specific_task:
2044 self._tp_service_specific_task[uni_id].clear()
2045 for uni_id in self._tech_profile_download_done:
2046 self._tech_profile_download_done[uni_id].clear()
2047 */
2048
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00002050
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002051 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00002052
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00002054 // abort: system behavior is just unstable ...
2055 return err
2056 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002058 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00002060 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002061 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00002063 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00002064 // abort: system behavior is just unstable ...
2065 return err
2066 }
2067 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002069 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002070 return nil
2071}
2072
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002073func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00002074 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
2075 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
2076 // as after down/up procedures all FSM's might be active/ongoing (in theory)
2077 // and using the stop/reset event should never harm
2078
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00002080 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002081 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002082 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2083 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002084 if pDevEntry.PDevOmciCC != nil {
mpagenko8cd1bf72021-06-22 10:11:19 +00002085 pDevEntry.PDevOmciCC.CancelRequestMonitoring(ctx)
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00002086 }
Holger Hildebrandtfb402a62021-05-26 14:40:49 +00002087 pDevEntry.mutexOnuImageStatus.RLock()
2088 if pDevEntry.pOnuImageStatus != nil {
2089 pDevEntry.pOnuImageStatus.CancelProcessing(ctx)
2090 }
2091 pDevEntry.mutexOnuImageStatus.RUnlock()
mpagenkoaa3afe92021-05-21 16:20:58 +00002092
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002093 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00002094 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00002095 }
2096 //MibDownload may run
2097 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2098 if pMibDlFsm != nil {
2099 _ = pMibDlFsm.Event(dlEvReset)
2100 }
2101 //port lock/unlock FSM's may be active
2102 if dh.pUnlockStateFsm != nil {
2103 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2104 }
2105 if dh.pLockStateFsm != nil {
2106 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
2107 }
2108 //techProfile related PonAniConfigFsm FSM may be active
2109 if dh.pOnuTP != nil {
2110 // should always be the case here
2111 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
2112 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08002113 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00002114 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08002115 }
mpagenko900ee4b2020-10-12 11:56:34 +00002116 }
2117 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00002118 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00002119 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00002120 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
2121 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00002122 dh.lockVlanConfig.RUnlock()
2123 //reset of all Fsm is always accompanied by global persistency data removal
2124 // no need to remove specific data
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00002125 pVlanFilterFsm.RequestClearPersistency(ctx, false)
mpagenko7d6bb022021-03-11 15:07:55 +00002126 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00002127 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00002128 } else {
2129 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00002130 }
2131 }
2132 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002133 if dh.getCollectorIsRunning() {
2134 // Stop collector routine
2135 dh.stopCollector <- true
2136 }
Himani Chawla1472c682021-03-17 17:11:14 +05302137 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05302138 dh.stopAlarmManager <- true
2139 }
2140
mpagenko80622a52021-02-09 16:53:23 +00002141 //reset a possibly running upgrade FSM
mpagenkoc26d4c02021-05-06 14:27:57 +00002142 // (note the Upgrade FSM may stay alive e.g. in state upgradeStWaitForCommit to endure the ONU reboot)
mpagenko80622a52021-02-09 16:53:23 +00002143 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002144 lopOnuUpradeFsm := dh.pOnuUpradeFsm
2145 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko80622a52021-02-09 16:53:23 +00002146 dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00002147 if lopOnuUpradeFsm != nil {
2148 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2149 //here we do not expect intermediate cancelation, we still allow for other commands on this FSM
2150 // (even though it may also run into direct cancellation, a bit hard to verify here)
2151 // so don't set 'dh.upgradeCanceled = true' here!
2152 lopOnuUpradeFsm.CancelProcessing(ctx, false, voltha.ImageState_CANCELLED_ON_ONU_STATE) //conditional cancel
2153 }
2154 }
mpagenko80622a52021-02-09 16:53:23 +00002155
mpagenko7d6bb022021-03-11 15:07:55 +00002156 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002157 return nil
2158}
2159
dbainbri4d3a0dc2020-12-02 00:33:42 +00002160func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2161 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 +05302162
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002163 // store persistent data collected during MIB upload processing
2164 if err := dh.storePersistentData(ctx); err != nil {
2165 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
2166 log.Fields{"device-id": dh.deviceID, "err": err})
2167 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002168 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002169 dh.addAllUniPorts(ctx)
2170
mpagenkoa40e99a2020-11-17 13:50:39 +00002171 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
2172 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
2173 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
2174 * disable/enable toggling here to allow traffic
2175 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
2176 * like the py comment says:
2177 * # start by locking all the unis till mib sync and initial mib is downloaded
2178 * # this way we can capture the port down/up events when we are ready
2179 */
Himani Chawla26e555c2020-08-31 12:30:20 +05302180
mpagenkoa40e99a2020-11-17 13:50:39 +00002181 // Init Uni Ports to Admin locked state
2182 // *** should generate UniLockStateDone event *****
2183 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00002185 } else { //LockStateFSM already init
2186 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002187 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00002188 }
2189}
2190
dbainbri4d3a0dc2020-12-02 00:33:42 +00002191func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2192 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302193 /* Mib download procedure -
2194 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
2195 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002197 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002198 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002199 return
2200 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302201 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
2202 if pMibDlFsm != nil {
2203 if pMibDlFsm.Is(dlStDisabled) {
2204 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002205 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 +05302206 // maybe try a FSM reset and then again ... - TODO!!!
2207 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002208 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302209 // maybe use more specific states here for the specific download steps ...
2210 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002211 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302212 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05302214 //Begin MIB data download (running autonomously)
2215 }
2216 }
2217 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002218 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00002219 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302220 // maybe try a FSM reset and then again ... - TODO!!!
2221 }
2222 /***** Mib download started */
2223 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302225 }
2226}
2227
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2229 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302230 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002231 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002232 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002233 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002234 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
2235 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
2236 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
2237 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302239 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
2240 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302242 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002243 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302244 }
2245 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05302247 log.Fields{"device-id": dh.deviceID})
2248 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002249 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08002250
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002251 if !dh.getCollectorIsRunning() {
2252 // Start PM collector routine
2253 go dh.startCollector(ctx)
2254 }
2255 if !dh.getAlarmManagerIsRunning(ctx) {
2256 go dh.startAlarmManager(ctx)
2257 }
2258
Girish Gowdrae0140f02021-02-02 16:55:09 -08002259 // Initialize classical L2 PM Interval Counters
2260 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
2261 // There is no way we should be landing here, but if we do then
2262 // there is nothing much we can do about this other than log error
2263 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
2264 }
2265
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002266 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002267
2268 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2269 if pDevEntry == nil {
2270 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2271 return
2272 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002273 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002274 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002275 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002276 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
2277 log.Fields{"device-id": dh.deviceID})
2278 go dh.reconcileDeviceTechProf(ctx)
2279 // reconcilement will be continued after ani config is done
2280 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002281 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002282 // *** should generate UniUnlockStateDone event *****
2283 if dh.pUnlockStateFsm == nil {
2284 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
2285 } else { //UnlockStateFSM already init
2286 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
2287 dh.runUniLockFsm(ctx, false)
2288 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302289 }
2290}
2291
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2293 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05302294
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002295 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002296 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
ozgecanetsia2f05ed32021-05-31 17:13:48 +03002297 raisedTs := time.Now().Unix()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002298 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
2299 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.PersUniUnlockDone = true
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 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302311 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 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 +05302313 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002314 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002315 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05302316 }
2317}
2318
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2320 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002321 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002322 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00002323 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
2324 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002326 }
2327
dbainbri4d3a0dc2020-12-02 00:33:42 +00002328 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002329 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002331
2332 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002334
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002336 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002337 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002338 return
2339 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002340 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002341 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002342 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002343 if err := dh.storePersistentData(ctx); err != nil {
2344 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002345 log.Fields{"device-id": dh.deviceID, "err": err})
2346 }
mpagenko900ee4b2020-10-12 11:56:34 +00002347}
2348
dbainbri4d3a0dc2020-12-02 00:33:42 +00002349func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2350 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002351 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00002353 voltha.OperStatus_ACTIVE); err != nil {
2354 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00002356 }
2357
dbainbri4d3a0dc2020-12-02 00:33:42 +00002358 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002359 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00002360 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00002362
2363 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002365
dbainbri4d3a0dc2020-12-02 00:33:42 +00002366 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002367 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002368 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002369 return
2370 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002371 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002372 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002373 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002374 if err := dh.storePersistentData(ctx); err != nil {
2375 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002376 log.Fields{"device-id": dh.deviceID, "err": err})
2377 }
mpagenko900ee4b2020-10-12 11:56:34 +00002378}
2379
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002380func (dh *deviceHandler) processUniEnableStateFailedEvent(ctx context.Context, devEvent OnuDeviceEvent) {
2381 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable failure. ", log.Fields{
2382 "OperStatus": voltha.OperStatus_FAILED, "device-id": dh.deviceID})
2383 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
2384 voltha.OperStatus_FAILED); err != nil {
2385 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
2386 }
2387}
2388
dbainbri4d3a0dc2020-12-02 00:33:42 +00002389func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002390 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002391 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002392 // attention: the device reason update is done based on ONU-UNI-Port related activity
2393 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002394 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002395 // 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 +00002396 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05302397 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002398 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002399 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002400 }
2401 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00002403 // attention: the device reason update is done based on ONU-UNI-Port related activity
2404 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002405 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00002406 // 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 +00002407 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00002408 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002409 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302410}
2411
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
2413 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00002414 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05302415 // attention: the device reason update is done based on ONU-UNI-Port related activity
2416 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302417
mpagenkof1fc3862021-02-16 10:09:52 +00002418 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002419 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002420 // which may be the case from some previous actvity on another UNI Port of the ONU
2421 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002422 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2423 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002424 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002425 }
2426 }
2427 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002428 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002429 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002431 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302432 }
mpagenkof1fc3862021-02-16 10:09:52 +00002433
2434 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2435 //events that request KvStore write
2436 if err := dh.storePersistentData(ctx); err != nil {
2437 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2438 log.Fields{"device-id": dh.deviceID, "err": err})
2439 }
2440 } else {
2441 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2442 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002443 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302444}
2445
Himani Chawla6d2ae152020-09-02 13:11:20 +05302446//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002447func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302448 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002449 case MibDatabaseSync:
2450 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002452 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002453 case UniLockStateDone:
2454 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002456 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002457 case MibDownloadDone:
2458 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002459 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002460 }
2461 case UniUnlockStateDone:
2462 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002463 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002464 }
mpagenko900ee4b2020-10-12 11:56:34 +00002465 case UniEnableStateDone:
2466 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002468 }
Holger Hildebrandtda15a092022-01-07 15:30:49 +00002469 case UniEnableStateFailed:
2470 {
2471 dh.processUniEnableStateFailedEvent(ctx, devEvent)
2472 }
mpagenko900ee4b2020-10-12 11:56:34 +00002473 case UniDisableStateDone:
2474 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002476 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002477 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002478 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002480 }
mpagenkof1fc3862021-02-16 10:09:52 +00002481 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002482 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002484 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002485 default:
2486 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002488 }
2489 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002490}
2491
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002493 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302495 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002496 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002498 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302499 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002500 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002501 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002502 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002503 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002504 //store UniPort with the System-PortNumber key
2505 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002506 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002507 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2509 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002510 } //error logging already within UniPort method
2511 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002512 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002513 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002514 }
2515 }
2516}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002517
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002518func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2519 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2520 if pDevEntry == nil {
2521 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2522 return
2523 }
2524 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2525 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2526 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2527 for _, mgmtEntityID := range pptpInstKeys {
2528 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2529 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2530 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2531 i++
2532 }
2533 } else {
2534 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2535 }
2536 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2537 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2538 for _, mgmtEntityID := range veipInstKeys {
2539 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2540 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2541 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2542 i++
2543 }
2544 } else {
2545 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2546 }
2547 if i == 0 {
2548 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2549 }
2550}
2551
mpagenko3af1f032020-06-10 08:53:41 +00002552// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002554 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302555 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002556 // with following remark:
2557 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2558 // # load on the core
2559
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002560 // 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 +00002561
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002562 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002563 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002564 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002565 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302566 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002567 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002568 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 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 +00002570 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002572 }
mpagenko3af1f032020-06-10 08:53:41 +00002573 }
2574 }
2575}
2576
2577// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002579 // compare enableUniPortStateUpdate() above
2580 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2581 for uniNo, uniPort := range dh.uniEntityMap {
2582 // only if this port is validated for operState transfer
Matteo Scandolo20d180c2021-06-10 17:20:21 +02002583
2584 if (1<<uniPort.uniID)&dh.pOpenOnuAc.config.UniPortMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002585 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302586 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002587 if !dh.isReconciling() {
2588 //maybe also use getter functions on uniPort - perhaps later ...
2589 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2590 } else {
2591 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2592 }
2593
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002594 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002595 }
2596}
2597
2598// ONU_Active/Inactive announcement on system KAFKA bus
2599// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002600func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002601 var de voltha.DeviceEvent
2602 eventContext := make(map[string]string)
2603 //Populating event context
2604 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002605 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002606 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302608 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt7ec14c42021-05-28 14:21:58 +00002609 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 +00002610 }
2611 oltSerialNumber := parentDevice.SerialNumber
2612
2613 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2614 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2615 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302616 eventContext["olt-serial-number"] = oltSerialNumber
2617 eventContext["device-id"] = aDeviceID
2618 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
ozgecanetsiaf0a76b62021-05-31 17:42:09 +03002619 eventContext["num-of-unis"] = strconv.Itoa(len(dh.uniEntityMap))
2620 if deviceEntry := dh.getOnuDeviceEntry(ctx, false); deviceEntry != nil {
2621 deviceEntry.mutexPersOnuConfig.RLock()
2622 eventContext["equipment-id"] = deviceEntry.sOnuPersistentData.PersEquipmentID
2623 deviceEntry.mutexPersOnuConfig.RUnlock()
2624 eventContext["software-version"] = deviceEntry.getActiveImageVersion(ctx)
2625 deviceEntry.mutexPersOnuConfig.RLock()
2626 eventContext["vendor"] = deviceEntry.sOnuPersistentData.PersVendorID
2627 deviceEntry.mutexPersOnuConfig.RUnlock()
2628 eventContext["inactive-software-version"] = deviceEntry.getInactiveImageVersion(ctx)
2629 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
2630 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
2631 } else {
2632 logger.Errorw(ctx, "Failed to fetch device-entry. ONU_ACTIVATED event is not sent",
2633 log.Fields{"device-id": aDeviceID})
2634 return
2635 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002636
2637 /* Populating device event body */
2638 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302639 de.ResourceId = aDeviceID
2640 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002641 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2642 de.Description = fmt.Sprintf("%s Event - %s - %s",
2643 cEventObjectType, cOnuActivatedEvent, "Raised")
2644 } else {
2645 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2646 de.Description = fmt.Sprintf("%s Event - %s - %s",
2647 cEventObjectType, cOnuActivatedEvent, "Cleared")
2648 }
2649 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2651 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302652 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002653 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302655 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002656}
2657
Himani Chawla4d908332020-08-31 12:30:20 +05302658// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002660 chLSFsm := make(chan Message, 2048)
2661 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302662 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002663 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002664 sFsmName = "LockStateFSM"
2665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002667 sFsmName = "UnLockStateFSM"
2668 }
mpagenko3af1f032020-06-10 08:53:41 +00002669
dbainbri4d3a0dc2020-12-02 00:33:42 +00002670 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002671 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002672 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002673 return
2674 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002675 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002676 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002677 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302678 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002679 dh.pLockStateFsm = pLSFsm
2680 } else {
2681 dh.pUnlockStateFsm = pLSFsm
2682 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002683 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002684 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002685 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002686 }
2687}
2688
2689// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002690func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002691 /* Uni Port lock/unlock procedure -
2692 ***** should run via 'adminDone' state and generate the argument requested event *****
2693 */
2694 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302695 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002696 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2697 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2698 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002699 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302700 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002701 }
2702 } else {
2703 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2704 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2705 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002706 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302707 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002708 }
2709 }
2710 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002711 if pLSStatemachine.Is(uniStDisabled) {
2712 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002714 // maybe try a FSM reset and then again ... - TODO!!!
2715 } else {
2716 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002717 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002718 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002719 }
2720 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002722 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002723 // maybe try a FSM reset and then again ... - TODO!!!
2724 }
2725 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002726 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002727 // maybe try a FSM reset and then again ... - TODO!!!
2728 }
2729}
2730
mpagenko80622a52021-02-09 16:53:23 +00002731// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002732// precondition: lockUpgradeFsm is already locked from caller of this function
mpagenko15ff4a52021-03-02 10:09:20 +00002733func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002734 //in here lockUpgradeFsm is already locked
2735 chUpgradeFsm := make(chan Message, 2048)
2736 var sFsmName = "OnuSwUpgradeFSM"
2737 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002738 if apDevEntry.PDevOmciCC == nil {
2739 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2740 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002741 }
mpagenko15ff4a52021-03-02 10:09:20 +00002742 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002743 sFsmName, chUpgradeFsm)
2744 if dh.pOnuUpradeFsm != nil {
2745 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2746 if pUpgradeStatemachine != nil {
2747 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2748 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2749 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2750 // maybe try a FSM reset and then again ... - TODO!!!
2751 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2752 }
mpagenko9c225032021-10-15 14:26:49 +00002753 /***** Upgrade FSM started */
2754 //reset the last stored upgrade states (which anyway should be don't care as long as the newly created FSM exists)
2755 (*dh.pLastUpgradeImageState).DownloadState = voltha.ImageState_DOWNLOAD_UNKNOWN
2756 (*dh.pLastUpgradeImageState).Reason = voltha.ImageState_NO_ERROR
2757 (*dh.pLastUpgradeImageState).ImageState = voltha.ImageState_IMAGE_UNKNOWN
mpagenko80622a52021-02-09 16:53:23 +00002758 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2759 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2760 } else {
2761 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2762 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2763 // maybe try a FSM reset and then again ... - TODO!!!
2764 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2765 }
2766 } else {
2767 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2768 // maybe try a FSM reset and then again ... - TODO!!!
2769 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2770 }
2771 } else {
2772 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2773 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2774 }
2775 return nil
2776}
2777
2778// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
mpagenko9c225032021-10-15 14:26:49 +00002779func (dh *deviceHandler) RemoveOnuUpgradeFsm(ctx context.Context, apImageState *voltha.ImageState) {
mpagenko80622a52021-02-09 16:53:23 +00002780 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2781 "device-id": dh.deviceID})
2782 dh.lockUpgradeFsm.Lock()
mpagenko9c225032021-10-15 14:26:49 +00002783 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2784 dh.upgradeCanceled = false //cancelation done
2785 dh.pLastUpgradeImageState = apImageState
2786 dh.lockUpgradeFsm.Unlock()
2787 //signal upgradeFsm removed using non-blocking channel send
2788 select {
2789 case dh.upgradeFsmChan <- struct{}{}:
2790 default:
2791 logger.Debugw(ctx, "removed-UpgradeFsm signal not send on upgradeFsmChan (no receiver)", log.Fields{
2792 "device-id": dh.deviceID})
2793 }
mpagenko80622a52021-02-09 16:53:23 +00002794}
2795
mpagenko15ff4a52021-03-02 10:09:20 +00002796// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2797func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2798 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2799 if pDevEntry == nil {
2800 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2801 return
2802 }
2803
2804 dh.lockUpgradeFsm.RLock()
mpagenko9c225032021-10-15 14:26:49 +00002805 //lockUpgradeFsm must be release before cancellation as this may implicitly request RemoveOnuUpgradeFsm()
mpagenko15ff4a52021-03-02 10:09:20 +00002806 if dh.pOnuUpradeFsm != nil {
mpagenko9c225032021-10-15 14:26:49 +00002807 if dh.upgradeCanceled { //avoid starting some new action in case it is already doing the cancelation
2808 dh.lockUpgradeFsm.RUnlock()
2809 logger.Errorw(ctx, "Some upgrade procedure still runs cancelation - abort", log.Fields{"device-id": dh.deviceID})
2810 return
2811 }
mpagenko15ff4a52021-03-02 10:09:20 +00002812 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2813 if pUpgradeStatemachine != nil {
2814 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2815 // (some manual forced commit could do without)
mpagenko1f8e8822021-06-25 14:10:21 +00002816 upgradeState := pUpgradeStatemachine.Current()
2817 if (upgradeState == upgradeStWaitForCommit) ||
2818 (upgradeState == upgradeStRequestingActivate) {
2819 // also include upgradeStRequestingActivate as it may be left in case the ActivateResponse just got lost
mpagenko183647c2021-06-08 15:25:04 +00002820 // 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 +00002821 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko1f8e8822021-06-25 14:10:21 +00002822 activeImageID, errImg := pDevEntry.GetActiveImageMeID(ctx)
2823 if errImg != nil {
mpagenko9c225032021-10-15 14:26:49 +00002824 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002825 logger.Errorw(ctx, "OnuSwUpgradeFSM abort - could not get active image after reboot",
2826 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00002827 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2828 dh.upgradeCanceled = true
2829 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2830 }
mpagenko15ff4a52021-03-02 10:09:20 +00002831 return
2832 }
mpagenko9c225032021-10-15 14:26:49 +00002833 dh.lockUpgradeFsm.RUnlock()
mpagenko1f8e8822021-06-25 14:10:21 +00002834 if activeImageID == dh.pOnuUpradeFsm.inactiveImageMeID {
2835 if (upgradeState == upgradeStRequestingActivate) && !dh.pOnuUpradeFsm.GetCommitFlag(ctx) {
2836 // if FSM was waiting on activateResponse, new image is active, but FSM shall not commit, then:
2837 if err := pUpgradeStatemachine.Event(upgradeEvActivationDone); err != nil {
2838 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call activate-done event", log.Fields{"err": err})
2839 return
2840 }
2841 logger.Debugw(ctx, "OnuSwUpgradeFSM activate-done after reboot", log.Fields{
2842 "state": upgradeState, "device-id": dh.deviceID})
2843 } else {
2844 //FSM in waitForCommit or (upgradeStRequestingActivate [lost ActivateResp] and commit allowed)
2845 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2846 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2847 return
2848 }
2849 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2850 "state": upgradeState, "device-id": dh.deviceID})
2851 }
2852 } else {
2853 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit/on ActivateResponse, but load did not start with expected image Id",
2854 log.Fields{"device-id": dh.deviceID})
mpagenko9c225032021-10-15 14:26:49 +00002855 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2856 dh.upgradeCanceled = true
2857 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2858 }
mpagenko1f8e8822021-06-25 14:10:21 +00002859 }
mpagenko15ff4a52021-03-02 10:09:20 +00002860 return
2861 }
mpagenko9c225032021-10-15 14:26:49 +00002862 dh.lockUpgradeFsm.RUnlock()
2863 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2864 log.Fields{"device-id": dh.deviceID})
2865 if !dh.upgradeCanceled { //avoid double cancelation in case it is already doing the cancelation
2866 dh.upgradeCanceled = true
2867 dh.pOnuUpradeFsm.CancelProcessing(ctx, true, voltha.ImageState_CANCELLED_ON_ONU_STATE) //complete abort
2868 }
2869 return
2870 }
2871 //upgrade FSM is active but not waiting for commit: maybe because commit flag is not set
2872 // upgrade FSM is to be informed if the current active image is the one that was used in upgrade for the download
2873 if activeImageID, err := pDevEntry.GetActiveImageMeID(ctx); err == nil {
2874 if dh.pOnuUpradeFsm.inactiveImageMeID == activeImageID {
2875 logger.Debugw(ctx, "OnuSwUpgradeFSM image state set to activated", log.Fields{
2876 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2877 dh.pOnuUpradeFsm.SetImageStateActive(ctx)
mpagenko183647c2021-06-08 15:25:04 +00002878 }
mpagenko15ff4a52021-03-02 10:09:20 +00002879 }
2880 }
2881 } else {
2882 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2883 }
mpagenko9c225032021-10-15 14:26:49 +00002884 dh.lockUpgradeFsm.RUnlock()
mpagenko15ff4a52021-03-02 10:09:20 +00002885}
2886
Himani Chawla6d2ae152020-09-02 13:11:20 +05302887//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002889
2890 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002891 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
Girish Gowdra50e56422021-06-01 16:46:04 -07002892 // kvbackend := db.NewBackend(ctx, dh.pOpenOnuAc.KVStoreType, dh.pOpenOnuAc.KVStoreAddress, dh.pOpenOnuAc.KVStoreTimeout, aBasePathKvStore)
mpagenkoaf801632020-07-03 10:00:42 +00002893 kvbackend := &db.Backend{
2894 Client: dh.pOpenOnuAc.kvClient,
2895 StoreType: dh.pOpenOnuAc.KVStoreType,
2896 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002897 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002898 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2899 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002900
mpagenkoaf801632020-07-03 10:00:42 +00002901 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002902}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002903func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302904 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002905
mpagenkodff5dda2020-08-28 11:52:01 +00002906 for _, field := range flow.GetOfbFields(apFlowItem) {
2907 switch field.Type {
2908 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2909 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002911 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2912 }
mpagenko01e726e2020-10-23 09:45:29 +00002913 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002914 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2915 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302916 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002917 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302918 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2919 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002920 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2921 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002922 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2923 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302924 return
mpagenkodff5dda2020-08-28 11:52:01 +00002925 }
2926 }
mpagenko01e726e2020-10-23 09:45:29 +00002927 */
mpagenkodff5dda2020-08-28 11:52:01 +00002928 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2929 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302930 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002931 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302932 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002933 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302934 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002935 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302937 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002938 }
2939 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2940 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302941 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002942 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002943 "PCP": loAddPcp})
2944 }
2945 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2946 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002947 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002948 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2949 }
2950 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2951 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002953 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2954 }
2955 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2956 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002957 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002958 "IPv4-DST": field.GetIpv4Dst()})
2959 }
2960 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2961 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002963 "IPv4-SRC": field.GetIpv4Src()})
2964 }
2965 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2966 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002967 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002968 "Metadata": field.GetTableMetadata()})
2969 }
2970 /*
2971 default:
2972 {
2973 //all other entires ignored
2974 }
2975 */
2976 }
2977 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302978}
mpagenkodff5dda2020-08-28 11:52:01 +00002979
dbainbri4d3a0dc2020-12-02 00:33:42 +00002980func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002981 for _, action := range flow.GetActions(apFlowItem) {
2982 switch action.Type {
2983 /* not used:
2984 case of.OfpActionType_OFPAT_OUTPUT:
2985 {
mpagenko01e726e2020-10-23 09:45:29 +00002986 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002987 "Output": action.GetOutput()})
2988 }
2989 */
2990 case of.OfpActionType_OFPAT_PUSH_VLAN:
2991 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002992 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002993 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2994 }
2995 case of.OfpActionType_OFPAT_SET_FIELD:
2996 {
2997 pActionSetField := action.GetSetField()
2998 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002999 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003000 "OxcmClass": pActionSetField.Field.OxmClass})
3001 }
3002 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05303003 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003004 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303005 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00003006 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05303007 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00003008 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05303009 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00003010 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003011 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003012 "Type": pActionSetField.Field.GetOfbField().Type})
3013 }
3014 }
3015 /*
3016 default:
3017 {
3018 //all other entires ignored
3019 }
3020 */
3021 }
3022 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05303023}
3024
3025//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
ozgecanetsia82b91a62021-05-21 18:54:49 +03003026func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort,
3027 apFlowMetaData *voltha.FlowMetadata) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05303028 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
3029 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
3030 var loAddPcp, loSetPcp uint8
3031 var loIPProto uint32
3032 /* the TechProfileId is part of the flow Metadata - compare also comment within
3033 * OLT-Adapter:openolt_flowmgr.go
3034 * Metadata 8 bytes:
3035 * Most Significant 2 Bytes = Inner VLAN
3036 * Next 2 Bytes = Tech Profile ID(TPID)
3037 * Least Significant 4 Bytes = Port ID
3038 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
3039 * subscriber related flows.
3040 */
3041
dbainbri4d3a0dc2020-12-02 00:33:42 +00003042 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05303043 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003044 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05303045 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00003046 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05303047 }
mpagenko551a4d42020-12-08 18:09:20 +00003048 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00003049 loCookie := apFlowItem.GetCookie()
3050 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00003051 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003052 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05303053
dbainbri4d3a0dc2020-12-02 00:33:42 +00003054 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00003055 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05303056 if loIPProto == 2 {
3057 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
3058 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00003059 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
3060 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303061 return nil
3062 }
mpagenko01e726e2020-10-23 09:45:29 +00003063 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003064 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00003065
3066 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003067 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003068 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
3069 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
3070 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
3071 //TODO!!: Use DeviceId within the error response to rwCore
3072 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00003073 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003074 }
3075 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003077 loSetVlan = loMatchVlan //both 'transparent' (copy any)
3078 } else {
3079 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
3080 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
3081 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05303082 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003083 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003084 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00003085 }
mpagenko9a304ea2020-12-16 15:54:01 +00003086
ozgecanetsia82b91a62021-05-21 18:54:49 +03003087 var meter *voltha.OfpMeterConfig
3088 if apFlowMetaData != nil {
3089 meter = apFlowMetaData.Meters[0]
3090 }
mpagenko2f487262021-08-23 15:59:06 +00003091 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
3092 // must be set including the execution of createVlanFilterFsm() to avoid unintended creation of FSM's
3093 // when different rules are requested concurrently for the same uni
3094 // (also vlan persistency data does not support multiple FSM's on the same UNI correctly!)
3095 dh.lockVlanAdd.Lock() //prevent multiple add activities to start in parallel
3096 dh.lockVlanConfig.RLock() //read protection on UniVlanConfigFsmMap (removeFlowItemFromUniPort)
3097 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID, "tpID": loTpID, "uniID": apUniPort.uniID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303098 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenko2f487262021-08-23 15:59:06 +00003099 //SetUniFlowParams() may block on some rule that is suspended-to-add
3100 // in order to allow for according flow removal lockVlanConfig may only be used with RLock here
mpagenkof1fc3862021-02-16 10:09:52 +00003101 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003102 loMatchVlan, loSetVlan, loSetPcp, false, meter)
mpagenko2f487262021-08-23 15:59:06 +00003103 dh.lockVlanConfig.RUnlock()
3104 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenkof1fc3862021-02-16 10:09:52 +00003105 return err
mpagenkodff5dda2020-08-28 11:52:01 +00003106 }
mpagenko2f487262021-08-23 15:59:06 +00003107 dh.lockVlanConfig.RUnlock()
3108 dh.lockVlanConfig.Lock() //createVlanFilterFsm should always be a non-blocking operation and requires r+w lock
mpagenko37047052021-07-27 10:01:29 +00003109 err := dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003110 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone, false, meter)
mpagenko37047052021-07-27 10:01:29 +00003111 dh.lockVlanConfig.Unlock()
mpagenko2f487262021-08-23 15:59:06 +00003112 dh.lockVlanAdd.Unlock() //re-admit new Add-flow-processing
mpagenko37047052021-07-27 10:01:29 +00003113 return err
mpagenko01e726e2020-10-23 09:45:29 +00003114}
3115
3116//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00003117func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00003118 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
3119 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
3120 //no extra check is done on the rule parameters
3121 //accordingly the removal is done only once - for the first found flow with that cookie, even though
3122 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
3123 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
3124 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00003125 // - 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 +00003126 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003127 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00003128
3129 /* TT related temporary workaround - should not be needed anymore
3130 for _, field := range flow.GetOfbFields(apFlowItem) {
3131 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
3132 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00003133 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00003134 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
3135 if loIPProto == 2 {
3136 // 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 +00003137 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00003138 log.Fields{"device-id": dh.deviceID})
3139 return nil
3140 }
3141 }
3142 } //for all OfbFields
3143 */
3144
mpagenko9a304ea2020-12-16 15:54:01 +00003145 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00003146 dh.lockVlanConfig.RLock()
3147 defer dh.lockVlanConfig.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00003148 logger.Debugw(ctx, "flow-remove got RLock", log.Fields{"device-id": dh.deviceID, "uniID": apUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +00003149 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003150 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00003151 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003152 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00003153 log.Fields{"device-id": dh.deviceID})
3154 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00003155 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00003156 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00003157
mpagenko01e726e2020-10-23 09:45:29 +00003158 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00003159}
3160
Himani Chawla26e555c2020-08-31 12:30:20 +05303161// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00003162// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko37047052021-07-27 10:01:29 +00003163// precondition: dh.lockVlanConfig is locked by the caller!
mpagenko551a4d42020-12-08 18:09:20 +00003164func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003165 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenkodff5dda2020-08-28 11:52:01 +00003166 chVlanFilterFsm := make(chan Message, 2048)
3167
dbainbri4d3a0dc2020-12-02 00:33:42 +00003168 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00003169 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003170 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303171 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003172 }
3173
dbainbri4d3a0dc2020-12-02 00:33:42 +00003174 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00003175 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003176 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, lastFlowToReconcile, aMeter)
mpagenkodff5dda2020-08-28 11:52:01 +00003177 if pVlanFilterFsm != nil {
mpagenko37047052021-07-27 10:01:29 +00003178 //dh.lockVlanConfig is locked (by caller) throughout the state transition to 'starting'
3179 // to prevent unintended (ignored) events to be sent there (from parallel processing)
Himani Chawla26e555c2020-08-31 12:30:20 +05303180 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00003181 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3182 if pVlanFilterStatemachine != nil {
3183 if pVlanFilterStatemachine.Is(vlanStDisabled) {
3184 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003185 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05303186 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003187 }
Himani Chawla26e555c2020-08-31 12:30:20 +05303188 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00003189 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05303190 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3191 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003192 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003193 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003194 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303195 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003196 }
3197 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003198 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003199 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05303200 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003201 }
3202 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003203 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003204 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05303205 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00003206 }
3207 return nil
3208}
3209
mpagenkofc4f56e2020-11-04 17:17:49 +00003210//VerifyVlanConfigRequest checks on existence of a given uniPort
3211// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00003212func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00003213 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
3214 var pCurrentUniPort *onuUniPort
3215 for _, uniPort := range dh.uniEntityMap {
3216 // only if this port is validated for operState transfer
3217 if uniPort.uniID == uint8(aUniID) {
3218 pCurrentUniPort = uniPort
3219 break //found - end search loop
3220 }
3221 }
3222 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003223 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00003224 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
3225 return
3226 }
mpagenko551a4d42020-12-08 18:09:20 +00003227 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00003228}
3229
mpagenkodff5dda2020-08-28 11:52:01 +00003230//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00003231func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00003232 //TODO!! verify and start pending flow configuration
3233 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
3234 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00003235
3236 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303237 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00003238 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003239 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
3240 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
3241 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00003242 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003243 if pVlanFilterFsm.GetWaitingTpID(ctx) == aTpID {
mpagenko551a4d42020-12-08 18:09:20 +00003244 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
3245 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
3246 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3247 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3248 } else {
3249 /***** UniVlanConfigFsm continued */
3250 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
3251 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3252 "UniPort": apUniPort.portNo})
3253 }
3254 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
3255 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
3256 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
3257 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
3258 } else {
3259 /***** UniVlanConfigFsm continued */
3260 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
3261 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3262 "UniPort": apUniPort.portNo})
3263 }
mpagenkodff5dda2020-08-28 11:52:01 +00003264 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003265 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
3266 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00003267 "UniPort": apUniPort.portNo})
3268 }
3269 } else {
mpagenko551a4d42020-12-08 18:09:20 +00003270 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
3271 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
3272 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00003273 }
3274 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003275 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00003276 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00003277 }
mpagenkof1fc3862021-02-16 10:09:52 +00003278 } else {
3279 dh.lockVlanConfig.RUnlock()
3280 }
mpagenkodff5dda2020-08-28 11:52:01 +00003281}
3282
3283//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
3284// 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 +00003285func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
3286 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00003287 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
3288 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00003289 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05303290 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00003291 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00003292}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003293
mpagenkof1fc3862021-02-16 10:09:52 +00003294//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
3295func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
3296 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
3297 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
3298 // obviously then parallel processing on the cancel must be avoided
3299 // deadline context to ensure completion of background routines waited for
3300 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
3301 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
3302 dctx, cancel := context.WithDeadline(context.Background(), deadline)
3303
3304 aPDevEntry.resetKvProcessingErrorIndication()
3305 var wg sync.WaitGroup
3306 wg.Add(1) // for the 1 go routine to finish
3307
3308 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
3309 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
3310
3311 return aPDevEntry.getKvProcessingErrorIndication()
3312}
3313
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003314//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
3315//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00003316func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
3317 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003318
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003319 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003320 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003321 return nil
3322 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003323 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003324
dbainbri4d3a0dc2020-12-02 00:33:42 +00003325 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003326 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003327 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003328 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3329 }
3330 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
3331
mpagenkof1fc3862021-02-16 10:09:52 +00003332 if aWriteToKvStore {
3333 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
3334 }
3335 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003336}
3337
dbainbri4d3a0dc2020-12-02 00:33:42 +00003338func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003339 defer cancel() //ensure termination of context (may be pro forma)
3340 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003341 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00003342 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00003343}
3344
dbainbri4d3a0dc2020-12-02 00:33:42 +00003345func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003346
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003347 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003348 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003349 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00003350 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
3351 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003352 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003353 return err
3354 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003355 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003356 return nil
3357 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00003358 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003359 return nil
3360}
3361
dbainbri4d3a0dc2020-12-02 00:33:42 +00003362func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
3363 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003364 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003365 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00003366 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
3367 }
mpagenkof1fc3862021-02-16 10:09:52 +00003368 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00003369}
3370
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003371// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003372// nolint: unused
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003373func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
3374 dh.lockDevice.RLock()
3375 defer dh.lockDevice.RUnlock()
3376 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
3377 return uniPort.entityID, nil
3378 }
3379 return 0, errors.New("error-fetching-uni-port")
3380}
Girish Gowdrae09a6202021-01-12 18:10:59 -08003381
3382// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003383func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
3384 var errorsList []error
3385 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 -08003386
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003387 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
3388 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
3389 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
3390
3391 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
3392 // successfully.
3393 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
3394 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
3395 if len(errorsList) > 0 {
3396 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3397 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003398 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003399 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
3400 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08003401}
3402
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003403func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3404 var err error
3405 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003406 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003407
3408 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
3409 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
3410 errorsList = append(errorsList, err)
3411 }
3412 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003413 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00003414
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003415 return errorsList
3416}
3417
3418func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3419 var err error
3420 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003421 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003422 // Check if group metric related config is updated
3423 for _, v := range pmConfigs.Groups {
3424 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
3425 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
3426 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3427
3428 if ok && m.frequency != v.GroupFreq {
3429 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
3430 errorsList = append(errorsList, err)
3431 }
3432 }
3433 if ok && m.enabled != v.Enabled {
3434 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
3435 errorsList = append(errorsList, err)
3436 }
3437 }
3438 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003439 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003440 return errorsList
3441}
3442
3443func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
3444 var err error
3445 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003446 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003447 // Check if standalone metric related config is updated
3448 for _, v := range pmConfigs.Metrics {
3449 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003450 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003451 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3452
3453 if ok && m.frequency != v.SampleFreq {
3454 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
3455 errorsList = append(errorsList, err)
3456 }
3457 }
3458 if ok && m.enabled != v.Enabled {
3459 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
3460 errorsList = append(errorsList, err)
3461 }
3462 }
3463 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08003464 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003465 return errorsList
3466}
3467
3468// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08003469func (dh *deviceHandler) startCollector(ctx context.Context) {
3470 logger.Debugf(ctx, "startingCollector")
3471
3472 // Start routine to process OMCI GET Responses
3473 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Himani Chawla43f95ff2021-06-03 00:24:12 +05303474 // Create Extended Frame PM ME
3475 go dh.pOnuMetricsMgr.createEthernetFrameExtendedPMME(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003476 // Initialize the next metric collection time.
3477 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
3478 // reset like onu rebooted.
3479 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003480 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003481 for {
3482 select {
3483 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003484 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08003485 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08003486 // Stop the L2 PM FSM
3487 go func() {
3488 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
3489 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
3490 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
3491 }
3492 } else {
3493 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
3494 }
3495 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07003496 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
3497 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
3498 }
3499 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
3500 dh.pOnuMetricsMgr.stopTicks <- true
3501 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08003502
Girish Gowdrae09a6202021-01-12 18:10:59 -08003503 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003504 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
3505 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
3506 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
3507 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
3508 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08003509 // Update the next metric collection time.
3510 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003511 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003512 } else {
3513 if dh.pmConfigs.Grouped { // metrics are managed as a group
3514 // parse through the group and standalone metrics to see it is time to collect their metrics
3515 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003516
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003517 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3518 // 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 -08003519 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3520 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003521 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3522 }
3523 }
3524 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3525 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3526 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3527 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3528 }
3529 }
3530 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3531
3532 // parse through the group and update the next metric collection time
3533 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3534 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3535 // 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 -08003536 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3537 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003538 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3539 }
3540 }
3541 // parse through the standalone metrics and update the next metric collection time
3542 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3543 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3544 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3545 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3546 }
3547 }
3548 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3549 } /* else { // metrics are not managed as a group
3550 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3551 } */
3552 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003553 }
3554 }
3555}
kesavandfdf77632021-01-26 23:40:33 -05003556
3557func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3558
3559 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3560 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3561}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003562
Himani Chawla43f95ff2021-06-03 00:24:12 +05303563func (dh *deviceHandler) getOnuOMCICounters(ctx context.Context, onuInfo *extension.GetOmciEthernetFrameExtendedPmRequest) *extension.SingleGetValueResponse {
3564 if dh.pOnuMetricsMgr == nil {
3565 return &extension.SingleGetValueResponse{
3566 Response: &extension.GetValueResponse{
3567 Status: extension.GetValueResponse_ERROR,
3568 ErrReason: extension.GetValueResponse_INTERNAL_ERROR,
3569 },
3570 }
3571 }
3572 resp := dh.pOnuMetricsMgr.collectEthernetFrameExtendedPMCounters(ctx)
3573 return resp
3574}
3575
mpagenkof1fc3862021-02-16 10:09:52 +00003576func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3577 if pFsm == nil {
3578 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003579 }
mpagenkof1fc3862021-02-16 10:09:52 +00003580 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003581}
3582
mpagenkof1fc3862021-02-16 10:09:52 +00003583func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
mpagenko9c225032021-10-15 14:26:49 +00003584 var pAdapterFsm *AdapterFsm
3585 //note/TODO!!: might be that access to all these specific FSM pointers need a semaphore protection as well, cmp lockUpgradeFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003586 switch omciFsm {
3587 case cUploadFsm:
3588 {
mpagenko9c225032021-10-15 14:26:49 +00003589 if dh.pOnuOmciDevice != nil {
3590 pAdapterFsm = dh.pOnuOmciDevice.pMibUploadFsm
3591 } else {
3592 return true //FSM not active - so there is no activity on omci
3593 }
mpagenkof1fc3862021-02-16 10:09:52 +00003594 }
3595 case cDownloadFsm:
3596 {
mpagenko9c225032021-10-15 14:26:49 +00003597 if dh.pOnuOmciDevice != nil {
3598 pAdapterFsm = dh.pOnuOmciDevice.pMibDownloadFsm
3599 } else {
3600 return true //FSM not active - so there is no activity on omci
3601 }
mpagenkof1fc3862021-02-16 10:09:52 +00003602 }
3603 case cUniLockFsm:
3604 {
mpagenko9c225032021-10-15 14:26:49 +00003605 if dh.pLockStateFsm != nil {
3606 pAdapterFsm = dh.pLockStateFsm.pAdaptFsm
3607 } else {
3608 return true //FSM not active - so there is no activity on omci
3609 }
mpagenkof1fc3862021-02-16 10:09:52 +00003610 }
3611 case cUniUnLockFsm:
3612 {
mpagenko9c225032021-10-15 14:26:49 +00003613 if dh.pUnlockStateFsm != nil {
3614 pAdapterFsm = dh.pUnlockStateFsm.pAdaptFsm
3615 } else {
3616 return true //FSM not active - so there is no activity on omci
3617 }
mpagenkof1fc3862021-02-16 10:09:52 +00003618 }
3619 case cL2PmFsm:
3620 {
mpagenko9c225032021-10-15 14:26:49 +00003621 if dh.pOnuMetricsMgr != nil {
3622 pAdapterFsm = dh.pOnuMetricsMgr.pAdaptFsm
mpagenkof1fc3862021-02-16 10:09:52 +00003623 } else {
3624 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003625 }
3626 }
mpagenko80622a52021-02-09 16:53:23 +00003627 case cOnuUpgradeFsm:
3628 {
3629 dh.lockUpgradeFsm.RLock()
3630 defer dh.lockUpgradeFsm.RUnlock()
mpagenko9c225032021-10-15 14:26:49 +00003631 if dh.pOnuUpradeFsm != nil {
3632 pAdapterFsm = dh.pOnuUpradeFsm.pAdaptFsm
3633 } else {
3634 return true //FSM not active - so there is no activity on omci
3635 }
mpagenko80622a52021-02-09 16:53:23 +00003636 }
mpagenkof1fc3862021-02-16 10:09:52 +00003637 default:
3638 {
3639 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3640 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3641 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003642 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003643 }
mpagenko9c225032021-10-15 14:26:49 +00003644 if pAdapterFsm != nil && pAdapterFsm.pFsm != nil {
3645 return dh.isFsmInOmciIdleState(ctx, pAdapterFsm.pFsm, wantedState)
3646 }
3647 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003648}
3649
mpagenkof1fc3862021-02-16 10:09:52 +00003650func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3651 for _, v := range dh.pOnuTP.pAniConfigFsm {
3652 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003653 return false
3654 }
3655 }
3656 return true
3657}
3658
mpagenkof1fc3862021-02-16 10:09:52 +00003659func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3660 dh.lockVlanConfig.RLock()
3661 defer dh.lockVlanConfig.RUnlock()
3662 for _, v := range dh.UniVlanConfigFsmMap {
3663 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3664 return false
3665 }
3666 }
3667 return true //FSM not active - so there is no activity on omci
3668}
3669
3670func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3671 dh.lockVlanConfig.RLock()
3672 defer dh.lockVlanConfig.RUnlock()
3673 for _, v := range dh.UniVlanConfigFsmMap {
3674 if v.pAdaptFsm.pFsm != nil {
3675 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3676 return true //there is at least one VLAN FSM with some active configuration
3677 }
3678 }
3679 }
3680 return false //there is no VLAN FSM with some active configuration
3681}
3682
3683func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3684 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3685 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3686 return false
3687 }
3688 }
3689 // a further check is done to identify, if at least some data traffic related configuration exists
3690 // 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])
3691 return dh.checkUserServiceExists(ctx)
3692}
3693
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003694func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3695 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3696 if err := dh.resetFsms(ctx, false); err != nil {
3697 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3698 // TODO: fatal error reset ONU, delete deviceHandler!
3699 return
3700 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003701 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003702 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003703}
3704
3705func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3706 dh.mutexCollectorFlag.Lock()
3707 dh.collectorIsRunning = flagValue
3708 dh.mutexCollectorFlag.Unlock()
3709}
3710
3711func (dh *deviceHandler) getCollectorIsRunning() bool {
3712 dh.mutexCollectorFlag.RLock()
3713 flagValue := dh.collectorIsRunning
3714 dh.mutexCollectorFlag.RUnlock()
3715 return flagValue
3716}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303717
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303718func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3719 dh.mutextAlarmManagerFlag.Lock()
3720 dh.alarmManagerIsRunning = flagValue
3721 dh.mutextAlarmManagerFlag.Unlock()
3722}
3723
Himani Chawla1472c682021-03-17 17:11:14 +05303724func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303725 dh.mutextAlarmManagerFlag.RLock()
3726 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303727 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303728 dh.mutextAlarmManagerFlag.RUnlock()
3729 return flagValue
3730}
3731
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303732func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3733 logger.Debugf(ctx, "startingAlarmManager")
3734
3735 // Start routine to process OMCI GET Responses
3736 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303737 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303738 if stop := <-dh.stopAlarmManager; stop {
3739 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303740 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303741 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303742 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3743 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3744 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303745 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303746 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303747 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3748 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303749 }
3750}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003751
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003752func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003753 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003754
Maninder7961d722021-06-16 22:10:28 +05303755 connectStatus := voltha.ConnectStatus_UNREACHABLE
3756 operState := voltha.OperStatus_UNKNOWN
3757
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003758 if !dh.isReconciling() {
3759 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003760 logger.Debugw(ctx, "wait for channel signal or timeout",
3761 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003762 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003763 case success := <-dh.chReconcilingFinished:
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003764 logger.Debugw(ctx, "reconciling finished signal received",
3765 log.Fields{"device-id": dh.deviceID, "dh.chReconcilingFinished": dh.chReconcilingFinished})
3766 // To guarantee that the case-branch below is completely processed before reconciling processing is continued,
3767 // dh.mutexReconcilingFlag is locked already here. Thereby it is ensured, that further reconciling processing is stopped
3768 // at next call of dh.IsReconciling() until dh.reconciling is set after informing core about finished reconciling below.
3769 // This change addresses a problem described in VOL-4533 where the flag dh.reconciling not yet reset causes the uni ports
3770 // not to be created in ONOS in function dh.addUniPort(), when reconciling was started in reason "starting-openomci".
3771 // TODO: Keeping the mutex beyond an RPC towards core seems justifiable, as the effects here are easily overseeable.
3772 // However, a later refactoring of the functionality remains unaffected.
3773 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003774 if success {
Maninderb5187552021-03-23 22:23:42 +05303775 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3776 logger.Errorw(ctx, "No valid OnuDevice - aborting Core DeviceStateUpdate",
3777 log.Fields{"device-id": dh.deviceID})
3778 } else {
mpagenkob59fbed2021-11-23 16:55:20 +00003779 onuDevEntry.mutexPersOnuConfig.RLock()
Maninderb5187552021-03-23 22:23:42 +05303780 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3781 connectStatus = voltha.ConnectStatus_REACHABLE
3782 if !onuDevEntry.sOnuPersistentData.PersUniDisableDone {
3783 if onuDevEntry.sOnuPersistentData.PersUniUnlockDone {
3784 operState = voltha.OperStatus_ACTIVE
3785 } else {
3786 operState = voltha.OperStatus_ACTIVATING
3787 }
3788 }
3789 } else if onuDevEntry.sOnuPersistentData.PersOperState == "down" ||
3790 onuDevEntry.sOnuPersistentData.PersOperState == "unknown" ||
3791 onuDevEntry.sOnuPersistentData.PersOperState == "" {
3792 operState = voltha.OperStatus_DISCOVERED
3793 }
mpagenkob59fbed2021-11-23 16:55:20 +00003794 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninderb5187552021-03-23 22:23:42 +05303795 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": operState})
Maninderb5187552021-03-23 22:23:42 +05303796 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003797 logger.Debugw(ctx, "reconciling has been finished in time",
3798 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303799 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, operState); err != nil {
3800 logger.Errorw(ctx, "unable to update device state to core",
3801 log.Fields{"device-id": dh.deviceID, "Err": err})
3802 }
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003803 } else {
Maninderb5187552021-03-23 22:23:42 +05303804 logger.Errorw(ctx, "wait for reconciling aborted",
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003805 log.Fields{"device-id": dh.deviceID})
Maninder7961d722021-06-16 22:10:28 +05303806
3807 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3808 logger.Errorw(ctx, "No valid OnuDevice",
3809 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003810 } else {
3811 onuDevEntry.mutexPersOnuConfig.RLock()
3812 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3813 connectStatus = voltha.ConnectStatus_REACHABLE
3814 }
3815 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05303816 }
3817
3818 dh.deviceReconcileFailedUpdate(ctx, drReconcileCanceled, connectStatus)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003819 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003820 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003821 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3822 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt6be98372022-01-06 14:49:08 +00003823 dh.mutexReconcilingFlag.Lock()
Maninder7961d722021-06-16 22:10:28 +05303824
3825 if onuDevEntry := dh.getOnuDeviceEntry(ctx, true); onuDevEntry == nil {
3826 logger.Errorw(ctx, "No valid OnuDevice",
3827 log.Fields{"device-id": dh.deviceID})
mpagenkob59fbed2021-11-23 16:55:20 +00003828 } else {
3829 onuDevEntry.mutexPersOnuConfig.RLock()
3830 if onuDevEntry.sOnuPersistentData.PersOperState == "up" {
3831 connectStatus = voltha.ConnectStatus_REACHABLE
3832 }
3833 onuDevEntry.mutexPersOnuConfig.RUnlock()
Maninder7961d722021-06-16 22:10:28 +05303834 }
Maninder7961d722021-06-16 22:10:28 +05303835 dh.deviceReconcileFailedUpdate(ctx, drReconcileMaxTimeout, connectStatus)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003836 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003837 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003838 dh.mutexReconcilingFlag.Unlock()
3839 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003840 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003841 dh.mutexReconcilingFlag.Lock()
3842 if skipOnuConfig {
3843 dh.reconciling = cSkipOnuConfigReconciling
3844 } else {
3845 dh.reconciling = cOnuConfigReconciling
3846 }
3847 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003848}
3849
Girish Gowdra50e56422021-06-01 16:46:04 -07003850func (dh *deviceHandler) stopReconciling(ctx context.Context, success bool) {
3851 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID, "success": success})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003852 if dh.isReconciling() {
Girish Gowdra50e56422021-06-01 16:46:04 -07003853 dh.chReconcilingFinished <- success
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003854 } else {
3855 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3856 }
3857}
3858
3859func (dh *deviceHandler) isReconciling() bool {
3860 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003861 defer dh.mutexReconcilingFlag.RUnlock()
3862 return dh.reconciling != cNoReconciling
3863}
3864
3865func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3866 dh.mutexReconcilingFlag.RLock()
3867 defer dh.mutexReconcilingFlag.RUnlock()
3868 return dh.reconciling == cSkipOnuConfigReconciling
3869}
3870
3871func (dh *deviceHandler) setDeviceReason(value uint8) {
3872 dh.mutexDeviceReason.Lock()
3873 dh.deviceReason = value
3874 dh.mutexDeviceReason.Unlock()
3875}
3876
3877func (dh *deviceHandler) getDeviceReason() uint8 {
3878 dh.mutexDeviceReason.RLock()
3879 value := dh.deviceReason
3880 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003881 return value
3882}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003883
3884func (dh *deviceHandler) getDeviceReasonString() string {
3885 return deviceReasonMap[dh.getDeviceReason()]
3886}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003887
3888func (dh *deviceHandler) setReconcilingFlows(value bool) {
3889 dh.mutexReconcilingFlowsFlag.Lock()
3890 dh.reconcilingFlows = value
3891 dh.mutexReconcilingFlowsFlag.Unlock()
3892}
3893
3894func (dh *deviceHandler) isReconcilingFlows() bool {
3895 dh.mutexReconcilingFlowsFlag.RLock()
3896 value := dh.reconcilingFlows
3897 dh.mutexReconcilingFlowsFlag.RUnlock()
3898 return value
3899}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003900
3901func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3902 dh.mutexReadyForOmciConfig.Lock()
3903 dh.readyForOmciConfig = flagValue
3904 dh.mutexReadyForOmciConfig.Unlock()
3905}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003906func (dh *deviceHandler) isReadyForOmciConfig() bool {
3907 dh.mutexReadyForOmciConfig.RLock()
3908 flagValue := dh.readyForOmciConfig
3909 dh.mutexReadyForOmciConfig.RUnlock()
3910 return flagValue
3911}
Maninder7961d722021-06-16 22:10:28 +05303912
3913func (dh *deviceHandler) deviceReconcileFailedUpdate(ctx context.Context, deviceReason uint8, connectStatus voltha.ConnectStatus_Types) {
3914 if err := dh.deviceReasonUpdate(ctx, deviceReason, true); err != nil {
3915 logger.Errorw(ctx, "unable to update device reason to core",
3916 log.Fields{"device-id": dh.deviceID, "Err": err})
3917 }
3918
3919 logger.Debugw(ctx, "Core DeviceStateUpdate", log.Fields{"connectStatus": connectStatus, "operState": voltha.OperStatus_RECONCILING_FAILED})
3920 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.deviceID, connectStatus, voltha.OperStatus_RECONCILING_FAILED); err != nil {
3921 logger.Errorw(ctx, "unable to update device state to core",
3922 log.Fields{"device-id": dh.deviceID, "Err": err})
3923 }
3924}
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003925
3926// GetUniVlanConfigFsm - returns pointer to UniVlanConfigFsm
3927func (dh *deviceHandler) GetUniVlanConfigFsm(uniID uint8) *UniVlanConfigFsm {
3928 dh.lockVlanConfig.RLock()
3929 value := dh.UniVlanConfigFsmMap[uniID]
3930 dh.lockVlanConfig.RUnlock()
3931 return value
3932}