blob: 15d8c4e6f823682a590fa290268ea8f0e1e2c124 [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
28 "github.com/gogo/protobuf/proto"
29 "github.com/golang/protobuf/ptypes"
30 "github.com/looplab/fsm"
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +000031 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000032 "github.com/opencord/voltha-lib-go/v4/pkg/adapters/adapterif"
33 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Himani Chawlac07fda02020-12-09 16:21:21 +053034 "github.com/opencord/voltha-lib-go/v4/pkg/events/eventif"
dbainbri4d3a0dc2020-12-02 00:33:42 +000035 flow "github.com/opencord/voltha-lib-go/v4/pkg/flows"
36 "github.com/opencord/voltha-lib-go/v4/pkg/log"
37 vc "github.com/opencord/voltha-protos/v4/go/common"
kesavandfdf77632021-01-26 23:40:33 -050038 "github.com/opencord/voltha-protos/v4/go/extension"
dbainbri4d3a0dc2020-12-02 00:33:42 +000039 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
40 "github.com/opencord/voltha-protos/v4/go/openflow_13"
41 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
42 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
43 oop "github.com/opencord/voltha-protos/v4/go/openolt"
44 "github.com/opencord/voltha-protos/v4/go/voltha"
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000045)
46
47/*
48// Constants for number of retries and for timeout
49const (
50 MaxRetry = 10
51 MaxTimeOutInMs = 500
52)
53*/
54
mpagenko1cc3cb42020-07-27 15:24:38 +000055const (
56 // events of Device FSM
57 devEvDeviceInit = "devEvDeviceInit"
58 devEvGrpcConnected = "devEvGrpcConnected"
59 devEvGrpcDisconnected = "devEvGrpcDisconnected"
60 devEvDeviceUpInd = "devEvDeviceUpInd"
61 devEvDeviceDownInd = "devEvDeviceDownInd"
62)
63const (
64 // states of Device FSM
65 devStNull = "devStNull"
66 devStDown = "devStDown"
67 devStInit = "devStInit"
68 devStConnected = "devStConnected"
69 devStUp = "devStUp"
70)
71
Holger Hildebrandt24d51952020-05-04 14:03:42 +000072//Event category and subcategory definitions - same as defiend for OLT in eventmgr.go - should be done more centrally
73const (
Himani Chawla4d908332020-08-31 12:30:20 +053074 pon = voltha.EventSubCategory_PON
75 //olt = voltha.EventSubCategory_OLT
76 //ont = voltha.EventSubCategory_ONT
77 //onu = voltha.EventSubCategory_ONU
78 //nni = voltha.EventSubCategory_NNI
79 //service = voltha.EventCategory_SERVICE
80 //security = voltha.EventCategory_SECURITY
81 equipment = voltha.EventCategory_EQUIPMENT
82 //processing = voltha.EventCategory_PROCESSING
83 //environment = voltha.EventCategory_ENVIRONMENT
84 //communication = voltha.EventCategory_COMMUNICATION
Holger Hildebrandt24d51952020-05-04 14:03:42 +000085)
86
87const (
88 cEventObjectType = "ONU"
89)
90const (
91 cOnuActivatedEvent = "ONU_ACTIVATED"
92)
93
Holger Hildebrandt10d98192021-01-27 15:29:31 +000094type usedOmciConfigFsms int
95
96const (
97 cUploadFsm usedOmciConfigFsms = iota
98 cDownloadFsm
99 cUniLockFsm
100 cUniUnLockFsm
101 cAniConfigFsm
102 cUniVlanConfigFsm
Girish Gowdrae0140f02021-02-02 16:55:09 -0800103 cL2PmFsm
mpagenko80622a52021-02-09 16:53:23 +0000104 cOnuUpgradeFsm
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000105)
106
mpagenkof1fc3862021-02-16 10:09:52 +0000107type omciIdleCheckStruct struct {
108 omciIdleCheckFunc func(*deviceHandler, context.Context, usedOmciConfigFsms, string) bool
109 omciIdleState string
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000110}
111
mpagenkof1fc3862021-02-16 10:09:52 +0000112var fsmOmciIdleStateFuncMap = map[usedOmciConfigFsms]omciIdleCheckStruct{
113 cUploadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibUlFsmIdleState},
114 cDownloadFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cMibDlFsmIdleState},
115 cUniLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
116 cUniUnLockFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cUniFsmIdleState},
117 cAniConfigFsm: {(*deviceHandler).isAniConfigFsmInOmciIdleState, cAniFsmIdleState},
118 cUniVlanConfigFsm: {(*deviceHandler).isUniVlanConfigFsmInOmciIdleState, cVlanFsmIdleState},
119 cL2PmFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cL2PmFsmIdleState},
mpagenko80622a52021-02-09 16:53:23 +0000120 cOnuUpgradeFsm: {(*deviceHandler).isFsmInOmciIdleStateDefault, cOnuUpgradeFsmIdleState},
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000121}
122
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000123const (
124 // device reasons
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000125 drUnset = 0
126 drActivatingOnu = 1
127 drStartingOpenomci = 2
128 drDiscoveryMibsyncComplete = 3
129 drInitialMibDownloaded = 4
130 drTechProfileConfigDownloadSuccess = 5
131 drOmciFlowsPushed = 6
132 drOmciAdminLock = 7
133 drOnuReenabled = 8
134 drStoppingOpenomci = 9
135 drRebooting = 10
136 drOmciFlowsDeleted = 11
137 drTechProfileConfigDeleteSuccess = 12
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000138)
139
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000140var deviceReasonMap = map[uint8]string{
141 drUnset: "unset",
142 drActivatingOnu: "activating-onu",
143 drStartingOpenomci: "starting-openomci",
144 drDiscoveryMibsyncComplete: "discovery-mibsync-complete",
145 drInitialMibDownloaded: "initial-mib-downloaded",
146 drTechProfileConfigDownloadSuccess: "tech-profile-config-download-success",
147 drOmciFlowsPushed: "omci-flows-pushed",
148 drOmciAdminLock: "omci-admin-lock",
149 drOnuReenabled: "onu-reenabled",
150 drStoppingOpenomci: "stopping-openomci",
151 drRebooting: "rebooting",
152 drOmciFlowsDeleted: "omci-flows-deleted",
153 drTechProfileConfigDeleteSuccess: "tech-profile-config-delete-success",
154}
155
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000156const (
157 cNoReconciling = iota
158 cOnuConfigReconciling
159 cSkipOnuConfigReconciling
160)
161
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162//deviceHandler will interact with the ONU ? device.
163type deviceHandler struct {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164 deviceID string
165 DeviceType string
166 adminState string
167 device *voltha.Device
168 logicalDeviceID string
169 ProxyAddressID string
170 ProxyAddressType string
Himani Chawla4d908332020-08-31 12:30:20 +0530171 parentID string
Holger Hildebrandt24d51952020-05-04 14:03:42 +0000172 ponPortNumber uint32
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000173
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000174 coreProxy adapterif.CoreProxy
175 AdapterProxy adapterif.AdapterProxy
Himani Chawlac07fda02020-12-09 16:21:21 +0530176 EventProxy eventif.EventProxy
Holger Hildebrandtc54939a2020-06-17 08:14:27 +0000177
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800178 pmConfigs *voltha.PmConfigs
Girish Gowdrae09a6202021-01-12 18:10:59 -0800179
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000180 pOpenOnuAc *OpenONUAC
181 pDeviceStateFsm *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +0530182 //pPonPort *voltha.Port
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000183 deviceEntrySet chan bool //channel for DeviceEntry set event
184 pOnuOmciDevice *OnuDeviceEntry
185 pOnuTP *onuUniTechProf
186 pOnuMetricsMgr *onuMetricsManager
187 pAlarmMgr *onuAlarmManager
Girish Gowdra6afb56a2021-04-27 17:47:57 -0700188 pSelfTestHdlr *selfTestControlBlock
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000189 exitChannel chan int
190 lockDevice sync.RWMutex
191 pOnuIndication *oop.OnuIndication
192 deviceReason uint8
193 mutexDeviceReason sync.RWMutex
194 pLockStateFsm *lockStateFsm
195 pUnlockStateFsm *lockStateFsm
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000197 //flowMgr *OpenOltFlowMgr
198 //eventMgr *OpenOltEventMgr
199 //resourceMgr *rsrcMgr.OpenOltResourceMgr
200
201 //discOnus sync.Map
202 //onus sync.Map
203 //portStats *OpenOltStatisticsMgr
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000204 collectorIsRunning bool
205 mutexCollectorFlag sync.RWMutex
206 stopCollector chan bool
207 alarmManagerIsRunning bool
208 mutextAlarmManagerFlag sync.RWMutex
209 stopAlarmManager chan bool
210 stopHeartbeatCheck chan bool
211 uniEntityMap map[uint32]*onuUniPort
212 mutexKvStoreContext sync.Mutex
213 lockVlanConfig sync.RWMutex
214 UniVlanConfigFsmMap map[uint8]*UniVlanConfigFsm
215 lockUpgradeFsm sync.RWMutex
216 pOnuUpradeFsm *OnuUpgradeFsm
217 reconciling uint8
218 mutexReconcilingFlag sync.RWMutex
219 chReconcilingFinished chan bool //channel to indicate that reconciling has been finished
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000220 reconcilingFlows bool
221 mutexReconcilingFlowsFlag sync.RWMutex
222 chReconcilingFlowsFinished chan bool //channel to indicate that reconciling of flows has been finished
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000223 ReadyForSpecificOmciConfig bool
224 deletionInProgress bool
225 mutexDeletionInProgressFlag sync.RWMutex
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000226}
227
Himani Chawla6d2ae152020-09-02 13:11:20 +0530228//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530229func 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 +0530230 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000231 dh.coreProxy = cp
232 dh.AdapterProxy = ap
233 dh.EventProxy = ep
234 cloned := (proto.Clone(device)).(*voltha.Device)
235 dh.deviceID = cloned.Id
236 dh.DeviceType = cloned.Type
237 dh.adminState = "up"
238 dh.device = cloned
239 dh.pOpenOnuAc = adapter
240 dh.exitChannel = make(chan int, 1)
241 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000242 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000243 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000244 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530245 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530246 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000247 dh.stopHeartbeatCheck = make(chan bool, 2)
248 //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 +0000249 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530250 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000251 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000252 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000253 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000254 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000255 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000256 dh.reconcilingFlows = false
257 dh.chReconcilingFlowsFinished = make(chan bool)
mpagenkofc4f56e2020-11-04 17:17:49 +0000258 dh.ReadyForSpecificOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000259 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000260
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800261 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
262 dh.pmConfigs = cloned.PmConfigs
263 } /* else {
264 // will be populated when onu_metrics_mananger is initialized.
265 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800266
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000267 // Device related state machine
268 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000269 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000270 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000271 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
272 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
273 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
274 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
275 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000276 },
277 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
279 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
280 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
281 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
282 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
283 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
284 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
285 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 },
287 )
mpagenkoaf801632020-07-03 10:00:42 +0000288
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000289 return &dh
290}
291
Himani Chawla6d2ae152020-09-02 13:11:20 +0530292// start save the device to the data model
293func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000294 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000295 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000296 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000297}
298
Himani Chawla4d908332020-08-31 12:30:20 +0530299/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000300// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530301func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000302 logger.Debug("stopping-device-handler")
303 dh.exitChannel <- 1
304}
Himani Chawla4d908332020-08-31 12:30:20 +0530305*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000306
307// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530308// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000309
Girish Gowdrae0140f02021-02-02 16:55:09 -0800310//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530311func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000312 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000313
dbainbri4d3a0dc2020-12-02 00:33:42 +0000314 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000315 if dh.pDeviceStateFsm.Is(devStNull) {
316 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000317 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000318 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000319 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800320 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
321 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800322 // Now, set the initial PM configuration for that device
323 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
324 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
325 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800326 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000327 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000329 }
330
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000331}
332
mpagenko057889c2021-01-21 16:51:58 +0000333func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530334 msgBody := msg.GetBody()
335 omciMsg := &ic.InterAdapterOmciMessage{}
336 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530338 "device-id": dh.deviceID, "error": err})
339 return err
340 }
341
mpagenko80622a52021-02-09 16:53:23 +0000342 /* 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 +0530343 //assuming omci message content is hex coded!
344 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000345 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530346 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000347 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530349 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000350 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000351 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000352 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000353 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 +0530354 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000355 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000356 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530357}
358
Himani Chawla6d2ae152020-09-02 13:11:20 +0530359func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000360 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530361 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000362
dbainbri4d3a0dc2020-12-02 00:33:42 +0000363 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000364
dbainbri4d3a0dc2020-12-02 00:33:42 +0000365 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000366 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000367 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000368 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
369 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530370 if dh.pOnuTP == nil {
371 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000372 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530373 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000374 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530375 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000376 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000377 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000378 "device-state": dh.getDeviceReasonString()})
379 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530380 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000381 //previous state test here was just this one, now extended for more states to reject the SetRequest:
382 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
383 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530384
385 msgBody := msg.GetBody()
386 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
387 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000388 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530389 "device-id": dh.deviceID, "error": err})
390 return err
391 }
392
393 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000394 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
395 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530396 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000397 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000398
399 if techProfMsg.UniId > 255 {
400 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
401 techProfMsg.UniId, dh.deviceID))
402 }
403 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800404 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
405 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000406 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800407 return err
408 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000409
dbainbri4d3a0dc2020-12-02 00:33:42 +0000410 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530411 // if there has been some change for some uni TechProfilePath
412 //in order to allow concurrent calls to other dh instances we do not wait for execution here
413 //but doing so we can not indicate problems to the caller (who does what with that then?)
414 //by now we just assume straightforward successful execution
415 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
416 // possible problems to the caller later autonomously
417
418 // deadline context to ensure completion of background routines waited for
419 //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 +0530420 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530421 dctx, cancel := context.WithDeadline(context.Background(), deadline)
422
Girish Gowdra041dcb32020-11-16 16:54:30 -0800423 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000424 pDevEntry.resetKvProcessingErrorIndication()
425
Himani Chawla26e555c2020-08-31 12:30:20 +0530426 var wg sync.WaitGroup
427 wg.Add(2) // for the 2 go routines to finish
428 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000429 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
430 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
431 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000432
Girish Gowdra041dcb32020-11-16 16:54:30 -0800433 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530434 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000435 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530436 return nil
437}
438
Himani Chawla6d2ae152020-09-02 13:11:20 +0530439func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000440 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530441 msg *ic.InterAdapterMessage) error {
442
dbainbri4d3a0dc2020-12-02 00:33:42 +0000443 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000444
dbainbri4d3a0dc2020-12-02 00:33:42 +0000445 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000446 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000447 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000448 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
449 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530450 if dh.pOnuTP == nil {
451 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000452 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530453 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000454 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530455 }
456
457 msgBody := msg.GetBody()
458 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
459 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000460 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530461 "device-id": dh.deviceID, "error": err})
462 return err
463 }
464
465 //compare TECH_PROFILE_DOWNLOAD_REQUEST
466 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000467 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530468
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000469 if delGemPortMsg.UniId > 255 {
470 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
471 delGemPortMsg.UniId, dh.deviceID))
472 }
473 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800474 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
475 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000476 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": delGemPortMsg.TpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800477 return err
478 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530479
mpagenkofc4f56e2020-11-04 17:17:49 +0000480 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000481
mpagenkofc4f56e2020-11-04 17:17:49 +0000482 // deadline context to ensure completion of background routines waited for
483 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
484 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000485
Girish Gowdra041dcb32020-11-16 16:54:30 -0800486 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000487
mpagenkofc4f56e2020-11-04 17:17:49 +0000488 var wg sync.WaitGroup
489 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000490 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000491 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000492 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000493
Girish Gowdra041dcb32020-11-16 16:54:30 -0800494 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530495}
496
Himani Chawla6d2ae152020-09-02 13:11:20 +0530497func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530499 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000500
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000502
dbainbri4d3a0dc2020-12-02 00:33:42 +0000503 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000504 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000505 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000506 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
507 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530508 if dh.pOnuTP == nil {
509 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000510 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530511 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000512 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530513 }
514
515 msgBody := msg.GetBody()
516 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
517 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000518 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530519 "device-id": dh.deviceID, "error": err})
520 return err
521 }
522
523 //compare TECH_PROFILE_DOWNLOAD_REQUEST
524 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000525 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526
527 if delTcontMsg.UniId > 255 {
528 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
529 delTcontMsg.UniId, dh.deviceID))
530 }
531 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800532 tpPath := delTcontMsg.TpPath
533 tpID, err := GetTpIDFromTpPath(tpPath)
534 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000535 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800536 return err
537 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000538
dbainbri4d3a0dc2020-12-02 00:33:42 +0000539 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530540 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530541 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530542 dctx, cancel := context.WithDeadline(context.Background(), deadline)
543
Girish Gowdra041dcb32020-11-16 16:54:30 -0800544 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000545 pDevEntry.resetKvProcessingErrorIndication()
546
Himani Chawla26e555c2020-08-31 12:30:20 +0530547 var wg sync.WaitGroup
548 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530550 cResourceTcont, delTcontMsg.AllocId, &wg)
551 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000552 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
553 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000554
Girish Gowdra041dcb32020-11-16 16:54:30 -0800555 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530556 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530557 return nil
558}
559
Himani Chawla6d2ae152020-09-02 13:11:20 +0530560//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000561// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
562// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000564 msgID := msg.Header.Id
565 msgType := msg.Header.Type
566 fromTopic := msg.Header.FromTopic
567 toTopic := msg.Header.ToTopic
568 toDeviceID := msg.Header.ToDeviceId
569 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000571 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
572
573 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000574 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000575 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
576 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000577 {
mpagenko057889c2021-01-21 16:51:58 +0000578 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000579 }
mpagenkoaf801632020-07-03 10:00:42 +0000580 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
581 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000582 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000583 }
584 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
585 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000586 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000587
mpagenkoaf801632020-07-03 10:00:42 +0000588 }
589 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
590 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000592 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000593 default:
594 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000595 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000596 "msgType": msg.Header.Type, "device-id": dh.deviceID})
597 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000598 }
599 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000600}
601
mpagenkodff5dda2020-08-28 11:52:01 +0000602//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000603func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
604 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000605 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000607
mpagenko01e726e2020-10-23 09:45:29 +0000608 var retError error = nil
609 //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 +0000610 if apOfFlowChanges.ToRemove != nil {
611 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000612 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000614 "device-id": dh.deviceID})
615 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000616 continue
617 }
618 flowInPort := flow.GetInPort(flowItem)
619 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000620 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 +0000621 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
622 continue
623 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000624 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000625 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000626 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000627 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000628 continue
629 } else {
630 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530631 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000632 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
633 loUniPort = uniPort
634 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000635 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000636 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
637 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
638 flowInPort, dh.deviceID)
639 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000640 }
641 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000643 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000644 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000645 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000646 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000647 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000648 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000649 log.Fields{"device-id": dh.deviceID, "error": err})
650 retError = err
651 continue
652 //return err
653 } else { // if last setting succeeds, overwrite possibly previously set error
654 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000655 }
656 }
657 }
658 }
mpagenko01e726e2020-10-23 09:45:29 +0000659 if apOfFlowChanges.ToAdd != nil {
660 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
661 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000663 "device-id": dh.deviceID})
664 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
665 continue
666 }
667 flowInPort := flow.GetInPort(flowItem)
668 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000669 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 +0000670 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
671 continue
672 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
673 } else if flowInPort == dh.ponPortNumber {
674 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000676 "device-id": dh.deviceID, "inPort": flowInPort})
677 continue
678 } else {
679 // this is the relevant upstream flow
680 var loUniPort *onuUniPort
681 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
682 loUniPort = uniPort
683 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000685 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
686 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
687 flowInPort, dh.deviceID)
688 continue
689 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
690 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000691 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
692 // if not, we just throw some error here to have an indication about that, if we really need to support that
693 // then we would need to create some means to activate the internal stored flows
694 // after the device gets active automatically (and still with its dependency to the TechProfile)
695 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
696 // also abort for the other still possible flows here
697 if !dh.ReadyForSpecificOmciConfig {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000699 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000700 return fmt.Errorf("improper device state on device %s", dh.deviceID)
701 }
702
mpagenko01e726e2020-10-23 09:45:29 +0000703 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000704 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000705 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
706 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000707 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000708 //try next flow after processing error
709 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000710 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000711 log.Fields{"device-id": dh.deviceID, "error": err})
712 retError = err
713 continue
714 //return err
715 } else { // if last setting succeeds, overwrite possibly previously set error
716 retError = nil
717 }
718 }
719 }
720 }
721 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000722}
723
Himani Chawla6d2ae152020-09-02 13:11:20 +0530724//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000725//following are the expected device states after this activity:
726//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
727// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000728func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
729 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000730
mpagenko900ee4b2020-10-12 11:56:34 +0000731 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000732 //note that disableDevice sequences in some 'ONU active' state may yield also
733 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000734 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000735 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000736 //disable-device shall be just a UNi/ONU-G related admin state setting
737 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000738
mpagenkofc4f56e2020-11-04 17:17:49 +0000739 if dh.ReadyForSpecificOmciConfig {
mpagenko01e726e2020-10-23 09:45:29 +0000740 // disable UNI ports/ONU
741 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
742 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000743 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000744 } else { //LockStateFSM already init
745 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000746 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000747 }
748 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000749 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000750 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000751 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000752 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
753 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000754 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000755 }
mpagenko01e726e2020-10-23 09:45:29 +0000756 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000757
758 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000759 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000760 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300761 }
762}
763
Himani Chawla6d2ae152020-09-02 13:11:20 +0530764//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000765func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
766 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000767
mpagenkofc4f56e2020-11-04 17:17:49 +0000768 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
769 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
770 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
771 // for real ONU's that should have nearly no influence
772 // Note that for real ONU's there is anyway a problematic situation with following sequence:
773 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
774 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
775 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
776 dh.ReadyForSpecificOmciConfig = true //needed to allow subsequent flow/techProf config (on BBSIM)
777
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000778 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000779 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000780 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000781 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000782 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000783 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000784 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000785 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300786}
787
dbainbri4d3a0dc2020-12-02 00:33:42 +0000788func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
789 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000790
dbainbri4d3a0dc2020-12-02 00:33:42 +0000791 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000792 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000793 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000794 return
795 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000797 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000798 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000799 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000800 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000801 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000802 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000803 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000804 }
Himani Chawla4d908332020-08-31 12:30:20 +0530805 var onuIndication oop.OnuIndication
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000806 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
807 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
808 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
809 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
dbainbri4d3a0dc2020-12-02 00:33:42 +0000810 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000811}
812
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
814 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000815
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000817 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000819 if !dh.isSkipOnuConfigReconciling() {
820 dh.stopReconciling(ctx)
821 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000822 return
823 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000824 dh.pOnuTP.lockTpProcMutex()
825 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000826 pDevEntry.persUniConfigMutex.RLock()
827 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000828
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000829 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000830 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000831 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000832 if !dh.isSkipOnuConfigReconciling() {
833 dh.stopReconciling(ctx)
834 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000835 return
836 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000837 techProfsFound := false
838 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000839 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000840 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
841 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000842 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000844 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000845 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000846 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800847 for tpID := range uniData.PersTpPathMap {
848 // deadline context to ensure completion of background routines waited for
849 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
850 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000852
Girish Gowdra041dcb32020-11-16 16:54:30 -0800853 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
854 var wg sync.WaitGroup
855 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
857 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800858 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800860 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000861 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000862 if len(uniData.PersFlowParams) != 0 {
863 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000864 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000865 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000866 if !techProfsFound {
867 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
868 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000869 if !dh.isSkipOnuConfigReconciling() {
870 dh.stopReconciling(ctx)
871 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000872 return
873 }
874 if dh.isSkipOnuConfigReconciling() {
875 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
876 }
877 if !flowsFound {
878 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
879 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000880 if !dh.isSkipOnuConfigReconciling() {
881 dh.stopReconciling(ctx)
882 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000883 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000884}
885
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
887 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000888
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000890 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000891 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000892 if !dh.isSkipOnuConfigReconciling() {
893 dh.stopReconciling(ctx)
894 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000895 return
896 }
Holger Hildebrandtdaf0f722021-02-12 11:50:30 +0000897 pDevEntry.persUniConfigMutex.RLock()
898 defer pDevEntry.persUniConfigMutex.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000899
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000900 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000901 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000902 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000903 if !dh.isSkipOnuConfigReconciling() {
904 dh.stopReconciling(ctx)
905 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000906 return
907 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000908 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000909 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000910 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
911 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000912 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000913 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000914 continue
915 }
916 if len(uniData.PersTpPathMap) == 0 {
917 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
918 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000919 // It doesn't make sense to configure any flows if no TPs are available
920 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000921 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000922 var uniPort *onuUniPort
923 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000924 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000925 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000926 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
927 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000928 if !dh.isSkipOnuConfigReconciling() {
929 dh.stopReconciling(ctx)
930 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000931 return
932 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000933 flowsFound = true
934 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000935 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000936 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000937 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000938 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000939 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000940 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000941 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000942 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
943 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000945 }
mpagenkof1fc3862021-02-16 10:09:52 +0000946 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000947 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000948 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000949 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000950 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000951 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000953 }
954 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000955 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000957 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
958 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
959 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000960 dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000961 }
962 if !flowsFound {
963 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
964 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000965 if !dh.isSkipOnuConfigReconciling() {
966 dh.stopReconciling(ctx)
967 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000968 return
969 }
970 if dh.isSkipOnuConfigReconciling() {
971 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000972 }
973}
974
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000975func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
976 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000977 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000978}
979
dbainbri4d3a0dc2020-12-02 00:33:42 +0000980func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
981 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000982
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000984 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000985 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000987 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000988 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000989
990 // deadline context to ensure completion of background routines waited for
991 //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 +0530992 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000993 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000994
995 pDevEntry.resetKvProcessingErrorIndication()
996
997 var wg sync.WaitGroup
998 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000999 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1000 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001001
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001002 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001003 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001004}
1005
mpagenko15ff4a52021-03-02 10:09:20 +00001006//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1007// before this change here return like this was used:
1008// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1009//was and is called in background - error return does not make sense
1010func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1011 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1012 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001013 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001014 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001015 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301017 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001018 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001019 return
Himani Chawla4d908332020-08-31 12:30:20 +05301020 }
mpagenko01e726e2020-10-23 09:45:29 +00001021
1022 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001023 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001024
dbainbri4d3a0dc2020-12-02 00:33:42 +00001025 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001026 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001028 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001029 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001030 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001031 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001032 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001034 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001035 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001036 dh.ReadyForSpecificOmciConfig = false
mpagenko8b07c1b2020-11-26 10:36:31 +00001037 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1038 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1039 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1040 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001041}
1042
mpagenkoc8bba412021-01-15 15:38:44 +00001043//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001044func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1045 apDownloadManager *adapterDownloadManager) error {
1046 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001047 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001048
1049 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001050 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1051 if pDevEntry == nil {
1052 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1053 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1054 }
1055
mpagenko80622a52021-02-09 16:53:23 +00001056 if dh.ReadyForSpecificOmciConfig {
mpagenko15ff4a52021-03-02 10:09:20 +00001057 var inactiveImageID uint16
1058 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1059 dh.lockUpgradeFsm.Lock()
1060 defer dh.lockUpgradeFsm.Unlock()
1061 if dh.pOnuUpradeFsm == nil {
1062 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1063 if err == nil {
1064 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1065 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1066 "device-id": dh.deviceID, "error": err})
1067 }
1068 } else {
1069 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001070 "device-id": dh.deviceID, "error": err})
1071 }
mpagenko15ff4a52021-03-02 10:09:20 +00001072 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1073 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1074 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1075 if pUpgradeStatemachine != nil {
1076 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1077 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1078 "device-id": dh.deviceID, "error": err})
1079 }
1080 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1081 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1082 // for now a second start of download should work again
1083 } else { //should never occur
1084 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1085 "device-id": dh.deviceID})
1086 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001087 }
mpagenko80622a52021-02-09 16:53:23 +00001088 }
mpagenko15ff4a52021-03-02 10:09:20 +00001089 } else {
1090 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1091 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001092 }
1093 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001094 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1095 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001096 }
1097 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001098}
1099
Himani Chawla6d2ae152020-09-02 13:11:20 +05301100// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001101// #####################################################################################
1102
1103// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301104// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001105
dbainbri4d3a0dc2020-12-02 00:33:42 +00001106func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1107 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 +00001108}
1109
1110// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001112
dbainbri4d3a0dc2020-12-02 00:33:42 +00001113 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001114 var err error
1115
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001116 // populate what we know. rest comes later after mib sync
1117 dh.device.Root = false
1118 dh.device.Vendor = "OpenONU"
1119 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001120 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001121 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001122
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001123 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001124
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001125 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001126 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1127 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301128 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001129 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001131 log.Fields{"device-id": dh.deviceID})
1132 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001133
Himani Chawla4d908332020-08-31 12:30:20 +05301134 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001135 dh.ponPortNumber = dh.device.ParentPortNo
1136
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001137 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1138 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1139 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001140 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001141 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301142 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001143
1144 /*
1145 self._pon = PonPort.create(self, self._pon_port_number)
1146 self._pon.add_peer(self.parent_id, self._pon_port_number)
1147 self.logger.debug('adding-pon-port-to-agent',
1148 type=self._pon.get_port().type,
1149 admin_state=self._pon.get_port().admin_state,
1150 oper_status=self._pon.get_port().oper_status,
1151 )
1152 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001153 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001154 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001155 var ponPortNo uint32 = 1
1156 if dh.ponPortNumber != 0 {
1157 ponPortNo = dh.ponPortNumber
1158 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001159
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001160 pPonPort := &voltha.Port{
1161 PortNo: ponPortNo,
1162 Label: fmt.Sprintf("pon-%d", ponPortNo),
1163 Type: voltha.Port_PON_ONU,
1164 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301165 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001166 PortNo: ponPortNo}}, // Peer port is parent's port number
1167 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001168 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1169 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001170 e.Cancel(err)
1171 return
1172 }
1173 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001174 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001175 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001176 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001177}
1178
1179// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001181
dbainbri4d3a0dc2020-12-02 00:33:42 +00001182 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001183 var err error
1184 /*
1185 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1186 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1187 return nil
1188 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001189 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1190 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001191 e.Cancel(err)
1192 return
1193 }
1194
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001195 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001197 // reconcilement will be continued after mib download is done
1198 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001199
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001200 /*
1201 ############################################################################
1202 # Setup Alarm handler
1203 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1204 device.serial_number)
1205 ############################################################################
1206 # Setup PM configuration for this device
1207 # Pass in ONU specific options
1208 kwargs = {
1209 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1210 'heartbeat': self.heartbeat,
1211 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1212 }
1213 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1214 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1215 self.logical_device_id, device.serial_number,
1216 grouped=True, freq_override=False, **kwargs)
1217 pm_config = self._pm_metrics.make_proto()
1218 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1219 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1220 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1221
1222 # Note, ONU ID and UNI intf set in add_uni_port method
1223 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1224 ani_ports=[self._pon])
1225
1226 # Code to Run OMCI Test Action
1227 kwargs_omci_test_action = {
1228 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1229 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1230 }
1231 serial_number = device.serial_number
1232 self._test_request = OmciTestRequest(self.core_proxy,
1233 self.omci_agent, self.device_id,
1234 AniG, serial_number,
1235 self.logical_device_id,
1236 exclusive=False,
1237 **kwargs_omci_test_action)
1238
1239 self.enabled = True
1240 else:
1241 self.logger.info('onu-already-activated')
1242 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001243
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001245}
1246
1247// doStateConnected get the device info and update to voltha core
1248// for comparison of the original method (not that easy to uncomment): compare here:
1249// voltha-openolt-adapter/adaptercore/device_handler.go
1250// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001252
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301254 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001255 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001257}
1258
1259// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001261
dbainbri4d3a0dc2020-12-02 00:33:42 +00001262 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301263 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001264 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001266
1267 /*
1268 // Synchronous call to update device state - this method is run in its own go routine
1269 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1270 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001271 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 +00001272 return err
1273 }
1274 return nil
1275 */
1276}
1277
1278// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001280
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001282 var err error
1283
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001284 device := dh.device
1285 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001286 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001287 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001288 e.Cancel(err)
1289 return
1290 }
1291
1292 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001293 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001294 /*
1295 // Update the all ports state on that device to disable
1296 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001297 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001298 return er
1299 }
1300
1301 //Update the device oper state and connection status
1302 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1303 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1304 dh.device = cloned
1305
1306 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001307 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001308 return er
1309 }
1310
1311 //get the child device for the parent device
1312 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1313 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001314 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001315 return err
1316 }
1317 for _, onuDevice := range onuDevices.Items {
1318
1319 // Update onu state as down in onu adapter
1320 onuInd := oop.OnuIndication{}
1321 onuInd.OperState = "down"
1322 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1323 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1324 if er != nil {
1325 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001326 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001327 //Do not return here and continue to process other ONUs
1328 }
1329 }
1330 // * Discovered ONUs entries need to be cleared , since after OLT
1331 // is up, it starts sending discovery indications again* /
1332 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001333 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001334 return nil
1335 */
Himani Chawla4d908332020-08-31 12:30:20 +05301336 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001337 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001338 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001339}
1340
Himani Chawla6d2ae152020-09-02 13:11:20 +05301341// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342// #################################################################################
1343
1344// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301345// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001346
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001347//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001348func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001349 dh.lockDevice.RLock()
1350 pOnuDeviceEntry := dh.pOnuOmciDevice
1351 if aWait && pOnuDeviceEntry == nil {
1352 //keep the read sema short to allow for subsequent write
1353 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001354 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001355 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1356 // so it might be needed to wait here for that event with some timeout
1357 select {
1358 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001360 return nil
1361 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001363 // if written now, we can return the written value without sema
1364 return dh.pOnuOmciDevice
1365 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001366 }
mpagenko3af1f032020-06-10 08:53:41 +00001367 dh.lockDevice.RUnlock()
1368 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001369}
1370
Himani Chawla6d2ae152020-09-02 13:11:20 +05301371//setOnuDeviceEntry sets the ONU device entry within the handler
1372func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001373 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001374 dh.lockDevice.Lock()
1375 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001376 dh.pOnuOmciDevice = apDeviceEntry
1377 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001378 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301379 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001380 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001381}
1382
Himani Chawla6d2ae152020-09-02 13:11:20 +05301383//addOnuDeviceEntry creates a new ONU device or returns the existing
1384func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001385 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001386
dbainbri4d3a0dc2020-12-02 00:33:42 +00001387 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001388 if deviceEntry == nil {
1389 /* costum_me_map in python code seems always to be None,
1390 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1391 /* also no 'clock' argument - usage open ...*/
1392 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001393 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001394 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001395 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301396 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001397 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001398 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001399 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001400 // fire deviceEntry ready event to spread to possibly waiting processing
1401 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001402 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001403 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001405 }
1406 // might be updated with some error handling !!!
1407 return nil
1408}
1409
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1411 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001412 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1413
1414 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001415
dbainbri4d3a0dc2020-12-02 00:33:42 +00001416 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001417 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001419 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1420 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001421 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 if err := dh.storePersistentData(ctx); err != nil {
1423 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001424 log.Fields{"device-id": dh.deviceID, "err": err})
1425 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001427 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001429 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1430 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001432 }
1433 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001435 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001436
1437 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 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 +00001439 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001440 dh.stopReconciling(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001441 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001442 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001443 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1444 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1445 // 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 +00001446 // 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 +00001447 // so let's just try to keep it simple ...
1448 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001449 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001450 if err != nil || device == nil {
1451 //TODO: needs to handle error scenarios
1452 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1453 return errors.New("Voltha Device not found")
1454 }
1455 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001456
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001458 return err
mpagenko3af1f032020-06-10 08:53:41 +00001459 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001460
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001461 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001462
1463 /* this might be a good time for Omci Verify message? */
1464 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001465 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001466 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001467 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001469
1470 /* give the handler some time here to wait for the OMCi verification result
1471 after Timeout start and try MibUpload FSM anyway
1472 (to prevent stopping on just not supported OMCI verification from ONU) */
1473 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001474 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001477 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001478 }
1479
1480 /* In py code it looks earlier (on activate ..)
1481 # Code to Run OMCI Test Action
1482 kwargs_omci_test_action = {
1483 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1484 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1485 }
1486 serial_number = device.serial_number
1487 self._test_request = OmciTestRequest(self.core_proxy,
1488 self.omci_agent, self.device_id,
1489 AniG, serial_number,
1490 self.logical_device_id,
1491 exclusive=False,
1492 **kwargs_omci_test_action)
1493 ...
1494 # Start test requests after a brief pause
1495 if not self._test_request_started:
1496 self._test_request_started = True
1497 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1498 reactor.callLater(tststart, self._test_request.start_collector)
1499
1500 */
1501 /* which is then: in omci_test_request.py : */
1502 /*
1503 def start_collector(self, callback=None):
1504 """
1505 Start the collection loop for an adapter if the frequency > 0
1506
1507 :param callback: (callable) Function to call to collect PM data
1508 """
1509 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1510 if callback is None:
1511 callback = self.perform_test_omci
1512
1513 if self.lc is None:
1514 self.lc = LoopingCall(callback)
1515
1516 if self.default_freq > 0:
1517 self.lc.start(interval=self.default_freq / 10)
1518
1519 def perform_test_omci(self):
1520 """
1521 Perform the initial test request
1522 """
1523 ani_g_entities = self._device.configuration.ani_g_entities
1524 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1525 is not None else None
1526 self._entity_id = ani_g_entities_ids[0]
1527 self.logger.info('perform-test', entity_class=self._entity_class,
1528 entity_id=self._entity_id)
1529 try:
1530 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1531 result = yield self._device.omci_cc.send(frame)
1532 if not result.fields['omci_message'].fields['success_code']:
1533 self.logger.info('Self-Test Submitted Successfully',
1534 code=result.fields[
1535 'omci_message'].fields['success_code'])
1536 else:
1537 raise TestFailure('Test Failure: {}'.format(
1538 result.fields['omci_message'].fields['success_code']))
1539 except TimeoutError as e:
1540 self.deferred.errback(failure.Failure(e))
1541
1542 except Exception as e:
1543 self.logger.exception('perform-test-Error', e=e,
1544 class_id=self._entity_class,
1545 entity_id=self._entity_id)
1546 self.deferred.errback(failure.Failure(e))
1547
1548 */
1549
1550 // PM related heartbeat??? !!!TODO....
1551 //self._heartbeat.enabled = True
1552
mpagenko1cc3cb42020-07-27 15:24:38 +00001553 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1554 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1555 * 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 +05301556 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001557 */
1558 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001559 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001560 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001561 if pMibUlFsm.Is(ulStDisabled) {
1562 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 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 +00001564 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301565 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301567 //Determine ONU status and start/re-start MIB Synchronization tasks
1568 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001569 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301570 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001571 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 +00001572 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001573 }
Himani Chawla4d908332020-08-31 12:30:20 +05301574 } else {
1575 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001576 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 +00001577 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301578 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001579 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001580 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001581 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001583 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001584 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001585 }
1586 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001588 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001589 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001590
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001591 if !dh.getCollectorIsRunning() {
1592 // Start PM collector routine
1593 go dh.startCollector(ctx)
1594 }
Himani Chawla1472c682021-03-17 17:11:14 +05301595 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301596 go dh.startAlarmManager(ctx)
1597 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301598
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001599 return nil
1600}
1601
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001603 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001604 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001605 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001607
mpagenko900ee4b2020-10-12 11:56:34 +00001608 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1609 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1610 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001611 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001613 log.Fields{"device-id": dh.deviceID, "error": err})
1614 // abort: system behavior is just unstable ...
1615 return err
1616 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001617 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 _ = 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 +00001619
1620 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1621 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1622 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001624 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001626 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001627 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001628 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001629
1630 //TODO!!! remove existing traffic profiles
1631 /* from py code, if TP's exist, remove them - not yet implemented
1632 self._tp = dict()
1633 # Let TP download happen again
1634 for uni_id in self._tp_service_specific_task:
1635 self._tp_service_specific_task[uni_id].clear()
1636 for uni_id in self._tech_profile_download_done:
1637 self._tech_profile_download_done[uni_id].clear()
1638 */
1639
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001641
mpagenkofc4f56e2020-11-04 17:17:49 +00001642 dh.ReadyForSpecificOmciConfig = false
1643
dbainbri4d3a0dc2020-12-02 00:33:42 +00001644 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001645 // abort: system behavior is just unstable ...
1646 return err
1647 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001649 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001651 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001652 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001654 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001655 // abort: system behavior is just unstable ...
1656 return err
1657 }
1658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001660 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001661 return nil
1662}
1663
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001664func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001665 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1666 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1667 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1668 // and using the stop/reset event should never harm
1669
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001671 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001672 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001673 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1674 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001675 if pDevEntry.PDevOmciCC != nil {
1676 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1677 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001678 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001679 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001680 }
1681 //MibDownload may run
1682 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1683 if pMibDlFsm != nil {
1684 _ = pMibDlFsm.Event(dlEvReset)
1685 }
1686 //port lock/unlock FSM's may be active
1687 if dh.pUnlockStateFsm != nil {
1688 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1689 }
1690 if dh.pLockStateFsm != nil {
1691 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1692 }
1693 //techProfile related PonAniConfigFsm FSM may be active
1694 if dh.pOnuTP != nil {
1695 // should always be the case here
1696 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1697 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001698 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001699 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001700 }
mpagenko900ee4b2020-10-12 11:56:34 +00001701 }
1702 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001703 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001704 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001705 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1706 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001707 dh.lockVlanConfig.RUnlock()
1708 //reset of all Fsm is always accompanied by global persistency data removal
1709 // no need to remove specific data
1710 pVlanFilterFsm.RequestClearPersistency(false)
1711 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001712 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001713 } else {
1714 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001715 }
1716 }
1717 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001718 if dh.getCollectorIsRunning() {
1719 // Stop collector routine
1720 dh.stopCollector <- true
1721 }
Himani Chawla1472c682021-03-17 17:11:14 +05301722 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301723 dh.stopAlarmManager <- true
1724 }
1725
mpagenko80622a52021-02-09 16:53:23 +00001726 //reset a possibly running upgrade FSM
1727 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1728 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1729 dh.lockUpgradeFsm.RLock()
1730 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001731 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1732 if pUpgradeStatemachine != nil {
1733 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1734 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1735 }
1736 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1737 }
1738 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001739 }
1740 dh.lockUpgradeFsm.RUnlock()
1741
mpagenko7d6bb022021-03-11 15:07:55 +00001742 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001743 return nil
1744}
1745
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1747 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 +05301748
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001749 // store persistent data collected during MIB upload processing
1750 if err := dh.storePersistentData(ctx); err != nil {
1751 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1752 log.Fields{"device-id": dh.deviceID, "err": err})
1753 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001754 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001755 dh.addAllUniPorts(ctx)
1756
mpagenkoa40e99a2020-11-17 13:50:39 +00001757 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1758 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1759 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1760 * disable/enable toggling here to allow traffic
1761 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1762 * like the py comment says:
1763 * # start by locking all the unis till mib sync and initial mib is downloaded
1764 * # this way we can capture the port down/up events when we are ready
1765 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301766
mpagenkoa40e99a2020-11-17 13:50:39 +00001767 // Init Uni Ports to Admin locked state
1768 // *** should generate UniLockStateDone event *****
1769 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001771 } else { //LockStateFSM already init
1772 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001774 }
1775}
1776
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1778 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301779 /* Mib download procedure -
1780 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1781 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001783 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001784 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001785 return
1786 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301787 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1788 if pMibDlFsm != nil {
1789 if pMibDlFsm.Is(dlStDisabled) {
1790 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 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 +05301792 // maybe try a FSM reset and then again ... - TODO!!!
1793 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301795 // maybe use more specific states here for the specific download steps ...
1796 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301798 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001799 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301800 //Begin MIB data download (running autonomously)
1801 }
1802 }
1803 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001805 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301806 // maybe try a FSM reset and then again ... - TODO!!!
1807 }
1808 /***** Mib download started */
1809 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301811 }
1812}
1813
dbainbri4d3a0dc2020-12-02 00:33:42 +00001814func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1815 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301816 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001817 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001819 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001820 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1821 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1822 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1823 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301825 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1826 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301828 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001829 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301830 }
1831 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301833 log.Fields{"device-id": dh.deviceID})
1834 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001835 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001836
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001837 if !dh.getCollectorIsRunning() {
1838 // Start PM collector routine
1839 go dh.startCollector(ctx)
1840 }
1841 if !dh.getAlarmManagerIsRunning(ctx) {
1842 go dh.startAlarmManager(ctx)
1843 }
1844
Girish Gowdrae0140f02021-02-02 16:55:09 -08001845 // Initialize classical L2 PM Interval Counters
1846 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1847 // There is no way we should be landing here, but if we do then
1848 // there is nothing much we can do about this other than log error
1849 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1850 }
1851
mpagenkofc4f56e2020-11-04 17:17:49 +00001852 dh.ReadyForSpecificOmciConfig = true
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001853
1854 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1855 if pDevEntry == nil {
1856 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1857 return
1858 }
1859 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
1860 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1861 log.Fields{"device-id": dh.deviceID})
1862 go dh.reconcileDeviceTechProf(ctx)
1863 // reconcilement will be continued after ani config is done
1864 } else {
1865 // *** should generate UniUnlockStateDone event *****
1866 if dh.pUnlockStateFsm == nil {
1867 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1868 } else { //UnlockStateFSM already init
1869 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1870 dh.runUniLockFsm(ctx, false)
1871 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301872 }
1873}
1874
dbainbri4d3a0dc2020-12-02 00:33:42 +00001875func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1876 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301877
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001878 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301880 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1882 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001883 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001884 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001885 return
1886 }
1887 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 if err := dh.storePersistentData(ctx); err != nil {
1889 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001890 log.Fields{"device-id": dh.deviceID, "err": err})
1891 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301892 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001893 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 +05301894 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001896 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301897 }
1898}
1899
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1901 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001902 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001904 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1905 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001907 }
1908
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001910 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001911 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001912
1913 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001915
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001917 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001919 return
1920 }
1921 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001922 if err := dh.storePersistentData(ctx); err != nil {
1923 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001924 log.Fields{"device-id": dh.deviceID, "err": err})
1925 }
mpagenko900ee4b2020-10-12 11:56:34 +00001926}
1927
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1929 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001930 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001931 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001932 voltha.OperStatus_ACTIVE); err != nil {
1933 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001935 }
1936
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001938 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001939 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001941
1942 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001944
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001946 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001947 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001948 return
1949 }
1950 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 if err := dh.storePersistentData(ctx); err != nil {
1952 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001953 log.Fields{"device-id": dh.deviceID, "err": err})
1954 }
mpagenko900ee4b2020-10-12 11:56:34 +00001955}
1956
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001958 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001960 // attention: the device reason update is done based on ONU-UNI-Port related activity
1961 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001962 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001963 // 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 +00001964 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301965 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001966 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001968 }
1969 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001971 // attention: the device reason update is done based on ONU-UNI-Port related activity
1972 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001973 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001974 // 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 +00001975 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001976 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001977 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301978}
1979
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1981 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001982 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301983 // attention: the device reason update is done based on ONU-UNI-Port related activity
1984 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05301985
mpagenkof1fc3862021-02-16 10:09:52 +00001986 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001987 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00001988 // which may be the case from some previous actvity on another UNI Port of the ONU
1989 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001990 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
1991 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001992 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001993 }
1994 }
1995 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001996 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00001997 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001999 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302000 }
mpagenkof1fc3862021-02-16 10:09:52 +00002001
2002 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2003 //events that request KvStore write
2004 if err := dh.storePersistentData(ctx); err != nil {
2005 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2006 log.Fields{"device-id": dh.deviceID, "err": err})
2007 }
2008 } else {
2009 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2010 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002011 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302012}
2013
Himani Chawla6d2ae152020-09-02 13:11:20 +05302014//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302016 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002017 case MibDatabaseSync:
2018 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002020 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002021 case UniLockStateDone:
2022 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002024 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002025 case MibDownloadDone:
2026 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002028 }
2029 case UniUnlockStateDone:
2030 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002032 }
mpagenko900ee4b2020-10-12 11:56:34 +00002033 case UniEnableStateDone:
2034 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002036 }
2037 case UniDisableStateDone:
2038 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002040 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002041 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002042 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002044 }
mpagenkof1fc3862021-02-16 10:09:52 +00002045 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002046 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002048 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002049 default:
2050 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002052 }
2053 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002054}
2055
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002057 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302059 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002060 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002062 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302063 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002065 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002067 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002068 //store UniPort with the System-PortNumber key
2069 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002070 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002071 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2073 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002074 } //error logging already within UniPort method
2075 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002077 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002078 }
2079 }
2080}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002081
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002082func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2083 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2084 if pDevEntry == nil {
2085 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2086 return
2087 }
2088 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2089 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2090 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2091 for _, mgmtEntityID := range pptpInstKeys {
2092 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2093 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2094 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2095 i++
2096 }
2097 } else {
2098 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2099 }
2100 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2101 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2102 for _, mgmtEntityID := range veipInstKeys {
2103 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2104 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2105 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2106 i++
2107 }
2108 } else {
2109 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2110 }
2111 if i == 0 {
2112 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2113 }
2114}
2115
mpagenko3af1f032020-06-10 08:53:41 +00002116// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002118 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302119 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002120 // with following remark:
2121 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2122 // # load on the core
2123
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002124 // 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 +00002125
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002126 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002127 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302128 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002129 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302130 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002131 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002132 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 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 +00002134 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002136 }
mpagenko3af1f032020-06-10 08:53:41 +00002137 }
2138 }
2139}
2140
2141// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002143 // compare enableUniPortStateUpdate() above
2144 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2145 for uniNo, uniPort := range dh.uniEntityMap {
2146 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302147 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002148 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302149 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002150 if !dh.isReconciling() {
2151 //maybe also use getter functions on uniPort - perhaps later ...
2152 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2153 } else {
2154 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2155 }
2156
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002157 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002158 }
2159}
2160
2161// ONU_Active/Inactive announcement on system KAFKA bus
2162// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002163func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002164 var de voltha.DeviceEvent
2165 eventContext := make(map[string]string)
2166 //Populating event context
2167 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002169 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302171 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002172 }
2173 oltSerialNumber := parentDevice.SerialNumber
2174
2175 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2176 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2177 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302178 eventContext["olt-serial-number"] = oltSerialNumber
2179 eventContext["device-id"] = aDeviceID
2180 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002182 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002183
2184 /* Populating device event body */
2185 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302186 de.ResourceId = aDeviceID
2187 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002188 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2189 de.Description = fmt.Sprintf("%s Event - %s - %s",
2190 cEventObjectType, cOnuActivatedEvent, "Raised")
2191 } else {
2192 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2193 de.Description = fmt.Sprintf("%s Event - %s - %s",
2194 cEventObjectType, cOnuActivatedEvent, "Cleared")
2195 }
2196 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2198 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302199 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002200 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002201 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302202 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002203}
2204
Himani Chawla4d908332020-08-31 12:30:20 +05302205// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002207 chLSFsm := make(chan Message, 2048)
2208 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302209 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002211 sFsmName = "LockStateFSM"
2212 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002214 sFsmName = "UnLockStateFSM"
2215 }
mpagenko3af1f032020-06-10 08:53:41 +00002216
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002218 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002219 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002220 return
2221 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002223 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002224 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302225 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002226 dh.pLockStateFsm = pLSFsm
2227 } else {
2228 dh.pUnlockStateFsm = pLSFsm
2229 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002230 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002231 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002232 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002233 }
2234}
2235
2236// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002237func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002238 /* Uni Port lock/unlock procedure -
2239 ***** should run via 'adminDone' state and generate the argument requested event *****
2240 */
2241 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302242 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002243 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2244 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2245 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002246 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302247 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002248 }
2249 } else {
2250 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2251 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2252 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002253 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302254 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002255 }
2256 }
2257 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002258 if pLSStatemachine.Is(uniStDisabled) {
2259 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002261 // maybe try a FSM reset and then again ... - TODO!!!
2262 } else {
2263 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002264 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002265 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002266 }
2267 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002268 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002269 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002270 // maybe try a FSM reset and then again ... - TODO!!!
2271 }
2272 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002273 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002274 // maybe try a FSM reset and then again ... - TODO!!!
2275 }
2276}
2277
mpagenko80622a52021-02-09 16:53:23 +00002278// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002279func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002280 //in here lockUpgradeFsm is already locked
2281 chUpgradeFsm := make(chan Message, 2048)
2282 var sFsmName = "OnuSwUpgradeFSM"
2283 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002284 if apDevEntry.PDevOmciCC == nil {
2285 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2286 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002287 }
mpagenko15ff4a52021-03-02 10:09:20 +00002288 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002289 sFsmName, chUpgradeFsm)
2290 if dh.pOnuUpradeFsm != nil {
2291 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2292 if pUpgradeStatemachine != nil {
2293 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2294 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2295 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2296 // maybe try a FSM reset and then again ... - TODO!!!
2297 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2298 }
2299 /***** LockStateFSM started */
2300 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2301 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2302 } else {
2303 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2304 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2305 // maybe try a FSM reset and then again ... - TODO!!!
2306 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2307 }
2308 } else {
2309 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2310 // maybe try a FSM reset and then again ... - TODO!!!
2311 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2312 }
2313 } else {
2314 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2315 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2316 }
2317 return nil
2318}
2319
2320// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2321func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2322 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2323 "device-id": dh.deviceID})
2324 dh.lockUpgradeFsm.Lock()
2325 defer dh.lockUpgradeFsm.Unlock()
2326 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2327}
2328
mpagenko15ff4a52021-03-02 10:09:20 +00002329// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2330func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2331 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2332 if pDevEntry == nil {
2333 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2334 return
2335 }
2336
2337 dh.lockUpgradeFsm.RLock()
2338 defer dh.lockUpgradeFsm.RUnlock()
2339 if dh.pOnuUpradeFsm != nil {
2340 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2341 if pUpgradeStatemachine != nil {
2342 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2343 // (some manual forced commit could do without)
2344 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002345 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002346 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2347 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2348 return
2349 }
2350 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2351 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2352 } else {
2353 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2354 log.Fields{"device-id": dh.deviceID})
2355 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2356 return
2357 }
2358 }
2359 }
2360 } else {
2361 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2362 }
2363}
2364
Himani Chawla6d2ae152020-09-02 13:11:20 +05302365//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002366func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002367
2368 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002369 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002370 kvbackend := &db.Backend{
2371 Client: dh.pOpenOnuAc.kvClient,
2372 StoreType: dh.pOpenOnuAc.KVStoreType,
2373 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002374 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002375 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2376 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002377
mpagenkoaf801632020-07-03 10:00:42 +00002378 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002379}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002380func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302381 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002382
mpagenkodff5dda2020-08-28 11:52:01 +00002383 for _, field := range flow.GetOfbFields(apFlowItem) {
2384 switch field.Type {
2385 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2386 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002388 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2389 }
mpagenko01e726e2020-10-23 09:45:29 +00002390 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002391 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2392 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302393 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002394 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302395 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2396 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002397 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2398 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002399 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2400 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302401 return
mpagenkodff5dda2020-08-28 11:52:01 +00002402 }
2403 }
mpagenko01e726e2020-10-23 09:45:29 +00002404 */
mpagenkodff5dda2020-08-28 11:52:01 +00002405 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2406 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302407 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002408 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002410 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002412 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002413 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302414 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002415 }
2416 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2417 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302418 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002419 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002420 "PCP": loAddPcp})
2421 }
2422 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2423 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002424 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002425 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2426 }
2427 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2428 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002429 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002430 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2431 }
2432 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2433 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002434 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002435 "IPv4-DST": field.GetIpv4Dst()})
2436 }
2437 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2438 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002439 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002440 "IPv4-SRC": field.GetIpv4Src()})
2441 }
2442 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2443 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002445 "Metadata": field.GetTableMetadata()})
2446 }
2447 /*
2448 default:
2449 {
2450 //all other entires ignored
2451 }
2452 */
2453 }
2454 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302455}
mpagenkodff5dda2020-08-28 11:52:01 +00002456
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002458 for _, action := range flow.GetActions(apFlowItem) {
2459 switch action.Type {
2460 /* not used:
2461 case of.OfpActionType_OFPAT_OUTPUT:
2462 {
mpagenko01e726e2020-10-23 09:45:29 +00002463 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002464 "Output": action.GetOutput()})
2465 }
2466 */
2467 case of.OfpActionType_OFPAT_PUSH_VLAN:
2468 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002469 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002470 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2471 }
2472 case of.OfpActionType_OFPAT_SET_FIELD:
2473 {
2474 pActionSetField := action.GetSetField()
2475 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002477 "OxcmClass": pActionSetField.Field.OxmClass})
2478 }
2479 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302480 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002481 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302482 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002483 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302484 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302486 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002487 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002489 "Type": pActionSetField.Field.GetOfbField().Type})
2490 }
2491 }
2492 /*
2493 default:
2494 {
2495 //all other entires ignored
2496 }
2497 */
2498 }
2499 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302500}
2501
2502//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002503func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302504 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2505 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2506 var loAddPcp, loSetPcp uint8
2507 var loIPProto uint32
2508 /* the TechProfileId is part of the flow Metadata - compare also comment within
2509 * OLT-Adapter:openolt_flowmgr.go
2510 * Metadata 8 bytes:
2511 * Most Significant 2 Bytes = Inner VLAN
2512 * Next 2 Bytes = Tech Profile ID(TPID)
2513 * Least Significant 4 Bytes = Port ID
2514 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2515 * subscriber related flows.
2516 */
2517
dbainbri4d3a0dc2020-12-02 00:33:42 +00002518 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302519 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302521 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002522 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302523 }
mpagenko551a4d42020-12-08 18:09:20 +00002524 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002525 loCookie := apFlowItem.GetCookie()
2526 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002528 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302529
dbainbri4d3a0dc2020-12-02 00:33:42 +00002530 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002531 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302532 if loIPProto == 2 {
2533 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2534 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002535 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2536 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302537 return nil
2538 }
mpagenko01e726e2020-10-23 09:45:29 +00002539 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002541
2542 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002544 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2545 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2546 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2547 //TODO!!: Use DeviceId within the error response to rwCore
2548 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002549 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002550 }
2551 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002553 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2554 } else {
2555 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2556 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2557 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302558 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002559 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002561 }
mpagenko9a304ea2020-12-16 15:54:01 +00002562
2563 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002564 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002565 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302566 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002567 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002568 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002569 dh.lockVlanConfig.RUnlock()
2570 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002571 }
mpagenkof1fc3862021-02-16 10:09:52 +00002572 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002573 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002574 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002575}
2576
2577//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002578func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002579 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2580 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2581 //no extra check is done on the rule parameters
2582 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2583 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2584 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2585 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002586 // - 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 +00002587 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002588 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002589
2590 /* TT related temporary workaround - should not be needed anymore
2591 for _, field := range flow.GetOfbFields(apFlowItem) {
2592 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2593 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002594 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002595 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2596 if loIPProto == 2 {
2597 // 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 +00002598 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002599 log.Fields{"device-id": dh.deviceID})
2600 return nil
2601 }
2602 }
2603 } //for all OfbFields
2604 */
2605
mpagenko9a304ea2020-12-16 15:54:01 +00002606 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002607 dh.lockVlanConfig.RLock()
2608 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002609 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002610 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002611 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002613 log.Fields{"device-id": dh.deviceID})
2614 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002615 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002616 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002617
mpagenko01e726e2020-10-23 09:45:29 +00002618 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002619}
2620
Himani Chawla26e555c2020-08-31 12:30:20 +05302621// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002622// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002623func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002624 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002625 chVlanFilterFsm := make(chan Message, 2048)
2626
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002628 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002629 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302630 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002631 }
2632
dbainbri4d3a0dc2020-12-02 00:33:42 +00002633 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002634 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2635 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002636 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002637 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002638 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2639 // (from parallel processing)
2640 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302641 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002642 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2643 if pVlanFilterStatemachine != nil {
2644 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2645 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002646 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302647 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002648 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302649 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002650 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302651 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2652 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002655 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302656 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002657 }
2658 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002660 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302661 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002662 }
2663 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002664 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002665 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302666 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002667 }
2668 return nil
2669}
2670
mpagenkofc4f56e2020-11-04 17:17:49 +00002671//VerifyVlanConfigRequest checks on existence of a given uniPort
2672// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002673func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002674 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2675 var pCurrentUniPort *onuUniPort
2676 for _, uniPort := range dh.uniEntityMap {
2677 // only if this port is validated for operState transfer
2678 if uniPort.uniID == uint8(aUniID) {
2679 pCurrentUniPort = uniPort
2680 break //found - end search loop
2681 }
2682 }
2683 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002685 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2686 return
2687 }
mpagenko551a4d42020-12-08 18:09:20 +00002688 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002689}
2690
mpagenkodff5dda2020-08-28 11:52:01 +00002691//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002692func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002693 //TODO!! verify and start pending flow configuration
2694 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2695 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002696
2697 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302698 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002699 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002700 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2701 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2702 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002703 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2704 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2705 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2706 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2707 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2708 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2709 } else {
2710 /***** UniVlanConfigFsm continued */
2711 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2712 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2713 "UniPort": apUniPort.portNo})
2714 }
2715 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2716 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2717 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2718 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2719 } else {
2720 /***** UniVlanConfigFsm continued */
2721 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2722 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2723 "UniPort": apUniPort.portNo})
2724 }
mpagenkodff5dda2020-08-28 11:52:01 +00002725 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002726 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2727 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002728 "UniPort": apUniPort.portNo})
2729 }
2730 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002731 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2732 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2733 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002734 }
2735 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002737 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002738 }
mpagenkof1fc3862021-02-16 10:09:52 +00002739 } else {
2740 dh.lockVlanConfig.RUnlock()
2741 }
mpagenkodff5dda2020-08-28 11:52:01 +00002742}
2743
2744//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2745// 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 +00002746func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2747 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002748 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2749 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002750 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302751 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002752 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002753}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002754
mpagenkof1fc3862021-02-16 10:09:52 +00002755//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2756func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2757 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2758 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2759 // obviously then parallel processing on the cancel must be avoided
2760 // deadline context to ensure completion of background routines waited for
2761 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2762 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2763 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2764
2765 aPDevEntry.resetKvProcessingErrorIndication()
2766 var wg sync.WaitGroup
2767 wg.Add(1) // for the 1 go routine to finish
2768
2769 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2770 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2771
2772 return aPDevEntry.getKvProcessingErrorIndication()
2773}
2774
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002775//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2776//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002777func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2778 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002779
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002780 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002781 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002782 return nil
2783 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002784 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002785
dbainbri4d3a0dc2020-12-02 00:33:42 +00002786 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002787 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002788 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002789 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2790 }
2791 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2792
mpagenkof1fc3862021-02-16 10:09:52 +00002793 if aWriteToKvStore {
2794 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2795 }
2796 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002797}
2798
dbainbri4d3a0dc2020-12-02 00:33:42 +00002799func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002800 defer cancel() //ensure termination of context (may be pro forma)
2801 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002803 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002804}
2805
dbainbri4d3a0dc2020-12-02 00:33:42 +00002806func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002807
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002808 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002809 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002810 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2812 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002813 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002814 return err
2815 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002816 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002817 return nil
2818 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002820 return nil
2821}
2822
dbainbri4d3a0dc2020-12-02 00:33:42 +00002823func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2824 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002825 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002826 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002827 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2828 }
mpagenkof1fc3862021-02-16 10:09:52 +00002829 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002830}
2831
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002832func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2833 var errStr string = ""
2834 for _, err := range errS {
2835 if err != nil {
2836 errStr = errStr + err.Error() + " "
2837 }
2838 }
2839 if errStr != "" {
2840 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2841 }
2842 return nil
2843}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844
2845// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2846func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2847 dh.lockDevice.RLock()
2848 defer dh.lockDevice.RUnlock()
2849 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2850 return uniPort.entityID, nil
2851 }
2852 return 0, errors.New("error-fetching-uni-port")
2853}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002854
2855// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002856func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2857 var errorsList []error
2858 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 -08002859
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002860 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2861 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2862 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2863
2864 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2865 // successfully.
2866 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2867 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2868 if len(errorsList) > 0 {
2869 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2870 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002871 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002872 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2873 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002874}
2875
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002876func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2877 var err error
2878 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002879 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002880
2881 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2882 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2883 errorsList = append(errorsList, err)
2884 }
2885 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002886 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002887
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002888 return errorsList
2889}
2890
2891func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2892 var err error
2893 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002894 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002895 // Check if group metric related config is updated
2896 for _, v := range pmConfigs.Groups {
2897 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2898 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2899 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2900
2901 if ok && m.frequency != v.GroupFreq {
2902 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2903 errorsList = append(errorsList, err)
2904 }
2905 }
2906 if ok && m.enabled != v.Enabled {
2907 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2908 errorsList = append(errorsList, err)
2909 }
2910 }
2911 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002912 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002913 return errorsList
2914}
2915
2916func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2917 var err error
2918 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002919 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002920 // Check if standalone metric related config is updated
2921 for _, v := range pmConfigs.Metrics {
2922 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002923 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002924 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2925
2926 if ok && m.frequency != v.SampleFreq {
2927 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2928 errorsList = append(errorsList, err)
2929 }
2930 }
2931 if ok && m.enabled != v.Enabled {
2932 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2933 errorsList = append(errorsList, err)
2934 }
2935 }
2936 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002937 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002938 return errorsList
2939}
2940
2941// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002942func (dh *deviceHandler) startCollector(ctx context.Context) {
2943 logger.Debugf(ctx, "startingCollector")
2944
2945 // Start routine to process OMCI GET Responses
2946 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002947 // Initialize the next metric collection time.
2948 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2949 // reset like onu rebooted.
2950 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002951 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002952 for {
2953 select {
2954 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002955 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002956 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002957 // Stop the L2 PM FSM
2958 go func() {
2959 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2960 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2961 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2962 }
2963 } else {
2964 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2965 }
2966 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002967 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2968 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2969 }
2970 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2971 dh.pOnuMetricsMgr.stopTicks <- true
2972 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002973
Girish Gowdrae09a6202021-01-12 18:10:59 -08002974 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002975 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2976 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2977 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2978 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2979 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002980 // Update the next metric collection time.
2981 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002982 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002983 } else {
2984 if dh.pmConfigs.Grouped { // metrics are managed as a group
2985 // parse through the group and standalone metrics to see it is time to collect their metrics
2986 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08002987
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002988 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
2989 // 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 -08002990 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
2991 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002992 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
2993 }
2994 }
2995 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
2996 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
2997 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
2998 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
2999 }
3000 }
3001 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3002
3003 // parse through the group and update the next metric collection time
3004 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3005 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3006 // 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 -08003007 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3008 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003009 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3010 }
3011 }
3012 // parse through the standalone metrics and update the next metric collection time
3013 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3014 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3015 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3016 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3017 }
3018 }
3019 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3020 } /* else { // metrics are not managed as a group
3021 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3022 } */
3023 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003024 }
3025 }
3026}
kesavandfdf77632021-01-26 23:40:33 -05003027
3028func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3029
3030 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3031 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3032}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003033
mpagenkof1fc3862021-02-16 10:09:52 +00003034func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3035 if pFsm == nil {
3036 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003037 }
mpagenkof1fc3862021-02-16 10:09:52 +00003038 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003039}
3040
mpagenkof1fc3862021-02-16 10:09:52 +00003041func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3042 var pFsm *fsm.FSM
3043 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3044 switch omciFsm {
3045 case cUploadFsm:
3046 {
3047 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3048 }
3049 case cDownloadFsm:
3050 {
3051 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3052 }
3053 case cUniLockFsm:
3054 {
3055 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3056 }
3057 case cUniUnLockFsm:
3058 {
3059 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3060 }
3061 case cL2PmFsm:
3062 {
3063 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3064 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3065 } else {
3066 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003067 }
3068 }
mpagenko80622a52021-02-09 16:53:23 +00003069 case cOnuUpgradeFsm:
3070 {
3071 dh.lockUpgradeFsm.RLock()
3072 defer dh.lockUpgradeFsm.RUnlock()
3073 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3074 }
mpagenkof1fc3862021-02-16 10:09:52 +00003075 default:
3076 {
3077 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3078 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3079 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003080 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003081 }
mpagenkof1fc3862021-02-16 10:09:52 +00003082 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003083}
3084
mpagenkof1fc3862021-02-16 10:09:52 +00003085func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3086 for _, v := range dh.pOnuTP.pAniConfigFsm {
3087 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003088 return false
3089 }
3090 }
3091 return true
3092}
3093
mpagenkof1fc3862021-02-16 10:09:52 +00003094func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3095 dh.lockVlanConfig.RLock()
3096 defer dh.lockVlanConfig.RUnlock()
3097 for _, v := range dh.UniVlanConfigFsmMap {
3098 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3099 return false
3100 }
3101 }
3102 return true //FSM not active - so there is no activity on omci
3103}
3104
3105func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3106 dh.lockVlanConfig.RLock()
3107 defer dh.lockVlanConfig.RUnlock()
3108 for _, v := range dh.UniVlanConfigFsmMap {
3109 if v.pAdaptFsm.pFsm != nil {
3110 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3111 return true //there is at least one VLAN FSM with some active configuration
3112 }
3113 }
3114 }
3115 return false //there is no VLAN FSM with some active configuration
3116}
3117
3118func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3119 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3120 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3121 return false
3122 }
3123 }
3124 // a further check is done to identify, if at least some data traffic related configuration exists
3125 // 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])
3126 return dh.checkUserServiceExists(ctx)
3127}
3128
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003129func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3130 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3131 if err := dh.resetFsms(ctx, false); err != nil {
3132 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3133 // TODO: fatal error reset ONU, delete deviceHandler!
3134 return
3135 }
3136 if !dh.getCollectorIsRunning() {
3137 // Start PM collector routine
3138 go dh.startCollector(ctx)
3139 }
Himani Chawla1472c682021-03-17 17:11:14 +05303140 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303141 go dh.startAlarmManager(ctx)
3142 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003143 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003144 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003145}
3146
3147func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3148 dh.mutexCollectorFlag.Lock()
3149 dh.collectorIsRunning = flagValue
3150 dh.mutexCollectorFlag.Unlock()
3151}
3152
3153func (dh *deviceHandler) getCollectorIsRunning() bool {
3154 dh.mutexCollectorFlag.RLock()
3155 flagValue := dh.collectorIsRunning
3156 dh.mutexCollectorFlag.RUnlock()
3157 return flagValue
3158}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303159
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303160func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3161 dh.mutextAlarmManagerFlag.Lock()
3162 dh.alarmManagerIsRunning = flagValue
3163 dh.mutextAlarmManagerFlag.Unlock()
3164}
3165
Himani Chawla1472c682021-03-17 17:11:14 +05303166func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303167 dh.mutextAlarmManagerFlag.RLock()
3168 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303169 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303170 dh.mutextAlarmManagerFlag.RUnlock()
3171 return flagValue
3172}
3173
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303174func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3175 logger.Debugf(ctx, "startingAlarmManager")
3176
3177 // Start routine to process OMCI GET Responses
3178 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303179 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303180 if stop := <-dh.stopAlarmManager; stop {
3181 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303182 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303183 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303184 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3185 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3186 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303187 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303188 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303189 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3190 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303191 }
3192}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003193
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003194func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003195 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003196
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003197 if !dh.isReconciling() {
3198 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003199 logger.Debugw(ctx, "wait for channel signal or timeout",
3200 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003201 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003202 case success := <-dh.chReconcilingFinished:
3203 if success {
3204 logger.Debugw(ctx, "reconciling has been finished in time",
3205 log.Fields{"device-id": dh.deviceID})
3206 } else {
3207 logger.Debugw(ctx, "wait for reconciling aborted",
3208 log.Fields{"device-id": dh.deviceID})
3209 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003210 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003211 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3212 log.Fields{"device-id": dh.deviceID})
3213 }
3214 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003215 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003216 dh.mutexReconcilingFlag.Unlock()
3217 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003218 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003219 dh.mutexReconcilingFlag.Lock()
3220 if skipOnuConfig {
3221 dh.reconciling = cSkipOnuConfigReconciling
3222 } else {
3223 dh.reconciling = cOnuConfigReconciling
3224 }
3225 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003226}
3227
3228func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3229 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3230 if dh.isReconciling() {
3231 dh.chReconcilingFinished <- true
3232 } else {
3233 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3234 }
3235}
3236
3237func (dh *deviceHandler) isReconciling() bool {
3238 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003239 defer dh.mutexReconcilingFlag.RUnlock()
3240 return dh.reconciling != cNoReconciling
3241}
3242
3243func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3244 dh.mutexReconcilingFlag.RLock()
3245 defer dh.mutexReconcilingFlag.RUnlock()
3246 return dh.reconciling == cSkipOnuConfigReconciling
3247}
3248
3249func (dh *deviceHandler) setDeviceReason(value uint8) {
3250 dh.mutexDeviceReason.Lock()
3251 dh.deviceReason = value
3252 dh.mutexDeviceReason.Unlock()
3253}
3254
3255func (dh *deviceHandler) getDeviceReason() uint8 {
3256 dh.mutexDeviceReason.RLock()
3257 value := dh.deviceReason
3258 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003259 return value
3260}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003261
3262func (dh *deviceHandler) getDeviceReasonString() string {
3263 return deviceReasonMap[dh.getDeviceReason()]
3264}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003265
3266func (dh *deviceHandler) setReconcilingFlows(value bool) {
3267 dh.mutexReconcilingFlowsFlag.Lock()
3268 dh.reconcilingFlows = value
3269 dh.mutexReconcilingFlowsFlag.Unlock()
3270}
3271
3272func (dh *deviceHandler) isReconcilingFlows() bool {
3273 dh.mutexReconcilingFlowsFlag.RLock()
3274 value := dh.reconcilingFlows
3275 dh.mutexReconcilingFlowsFlag.RUnlock()
3276 return value
3277}