blob: 07fa67bbf97b72fc4db883c870077c21532009ed [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 Hildebrandt0da7e6f2021-05-12 13:08:43 +0000223 mutexReadyForOmciConfig sync.RWMutex
224 readyForOmciConfig bool
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000225 deletionInProgress bool
226 mutexDeletionInProgressFlag sync.RWMutex
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227}
228
Himani Chawla6d2ae152020-09-02 13:11:20 +0530229//newDeviceHandler creates a new device handler
Himani Chawlac07fda02020-12-09 16:21:21 +0530230func 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 +0530231 var dh deviceHandler
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000232 dh.coreProxy = cp
233 dh.AdapterProxy = ap
234 dh.EventProxy = ep
235 cloned := (proto.Clone(device)).(*voltha.Device)
236 dh.deviceID = cloned.Id
237 dh.DeviceType = cloned.Type
238 dh.adminState = "up"
239 dh.device = cloned
240 dh.pOpenOnuAc = adapter
241 dh.exitChannel = make(chan int, 1)
242 dh.lockDevice = sync.RWMutex{}
mpagenko3af1f032020-06-10 08:53:41 +0000243 dh.deviceEntrySet = make(chan bool, 1)
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000244 dh.collectorIsRunning = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000245 dh.stopCollector = make(chan bool, 2)
Himani Chawla4c1d4c72021-02-18 12:14:31 +0530246 dh.alarmManagerIsRunning = false
Himani Chawlaac1f5ad2021-02-04 21:21:54 +0530247 dh.stopAlarmManager = make(chan bool, 2)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000248 dh.stopHeartbeatCheck = make(chan bool, 2)
249 //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 +0000250 //TODO initialize the support classes.
Himani Chawla6d2ae152020-09-02 13:11:20 +0530251 dh.uniEntityMap = make(map[uint32]*onuUniPort)
mpagenkof1fc3862021-02-16 10:09:52 +0000252 dh.lockVlanConfig = sync.RWMutex{}
mpagenko80622a52021-02-09 16:53:23 +0000253 dh.lockUpgradeFsm = sync.RWMutex{}
mpagenkodff5dda2020-08-28 11:52:01 +0000254 dh.UniVlanConfigFsmMap = make(map[uint8]*UniVlanConfigFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000255 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000256 dh.chReconcilingFinished = make(chan bool)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000257 dh.reconcilingFlows = false
258 dh.chReconcilingFlowsFinished = make(chan bool)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000259 dh.readyForOmciConfig = false
Holger Hildebrandtff05b682021-03-16 15:02:05 +0000260 dh.deletionInProgress = false
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000261
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800262 if dh.device.PmConfigs != nil { // can happen after onu adapter restart
263 dh.pmConfigs = cloned.PmConfigs
264 } /* else {
265 // will be populated when onu_metrics_mananger is initialized.
266 }*/
Girish Gowdrae09a6202021-01-12 18:10:59 -0800267
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000268 // Device related state machine
269 dh.pDeviceStateFsm = fsm.NewFSM(
mpagenko1cc3cb42020-07-27 15:24:38 +0000270 devStNull,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000271 fsm.Events{
mpagenko1cc3cb42020-07-27 15:24:38 +0000272 {Name: devEvDeviceInit, Src: []string{devStNull, devStDown}, Dst: devStInit},
273 {Name: devEvGrpcConnected, Src: []string{devStInit}, Dst: devStConnected},
274 {Name: devEvGrpcDisconnected, Src: []string{devStConnected, devStDown}, Dst: devStInit},
275 {Name: devEvDeviceUpInd, Src: []string{devStConnected, devStDown}, Dst: devStUp},
276 {Name: devEvDeviceDownInd, Src: []string{devStUp}, Dst: devStDown},
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000277 },
278 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000279 "before_event": func(e *fsm.Event) { dh.logStateChange(ctx, e) },
280 ("before_" + devEvDeviceInit): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
281 ("after_" + devEvDeviceInit): func(e *fsm.Event) { dh.postInit(ctx, e) },
282 ("before_" + devEvGrpcConnected): func(e *fsm.Event) { dh.doStateConnected(ctx, e) },
283 ("before_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.doStateInit(ctx, e) },
284 ("after_" + devEvGrpcDisconnected): func(e *fsm.Event) { dh.postInit(ctx, e) },
285 ("before_" + devEvDeviceUpInd): func(e *fsm.Event) { dh.doStateUp(ctx, e) },
286 ("before_" + devEvDeviceDownInd): func(e *fsm.Event) { dh.doStateDown(ctx, e) },
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000287 },
288 )
mpagenkoaf801632020-07-03 10:00:42 +0000289
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000290 return &dh
291}
292
Himani Chawla6d2ae152020-09-02 13:11:20 +0530293// start save the device to the data model
294func (dh *deviceHandler) start(ctx context.Context) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000295 logger.Debugw(ctx, "starting-device-handler", log.Fields{"device": dh.device, "device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000296 // Add the initial device to the local model
dbainbri4d3a0dc2020-12-02 00:33:42 +0000297 logger.Debug(ctx, "device-handler-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000298}
299
Himani Chawla4d908332020-08-31 12:30:20 +0530300/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000301// stop stops the device dh. Not much to do for now
Himani Chawla6d2ae152020-09-02 13:11:20 +0530302func (dh *deviceHandler) stop(ctx context.Context) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000303 logger.Debug("stopping-device-handler")
304 dh.exitChannel <- 1
305}
Himani Chawla4d908332020-08-31 12:30:20 +0530306*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000307
308// ##########################################################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +0530309// deviceHandler methods that implement the adapters interface requests ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000310
Girish Gowdrae0140f02021-02-02 16:55:09 -0800311//adoptOrReconcileDevice adopts the ONU device
Himani Chawla6d2ae152020-09-02 13:11:20 +0530312func (dh *deviceHandler) adoptOrReconcileDevice(ctx context.Context, device *voltha.Device) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000313 logger.Debugw(ctx, "Adopt_or_reconcile_device", log.Fields{"device-id": device.Id, "Address": device.GetHostAndPort()})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000314
dbainbri4d3a0dc2020-12-02 00:33:42 +0000315 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
mpagenko1cc3cb42020-07-27 15:24:38 +0000316 if dh.pDeviceStateFsm.Is(devStNull) {
317 if err := dh.pDeviceStateFsm.Event(devEvDeviceInit); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000318 logger.Errorw(ctx, "Device FSM: Can't go to state DeviceInit", log.Fields{"err": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000319 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000320 logger.Debugw(ctx, "Device FSM: ", log.Fields{"state": string(dh.pDeviceStateFsm.Current())})
Girish Gowdraaf0ad632021-01-27 13:00:01 -0800321 // device.PmConfigs is not nil in cases when adapter restarts. We should not re-set the core again.
322 if device.PmConfigs == nil {
Girish Gowdra5a7c4922021-01-22 18:33:41 -0800323 // Now, set the initial PM configuration for that device
324 if err := dh.coreProxy.DevicePMConfigUpdate(ctx, dh.pmConfigs); err != nil {
325 logger.Errorw(ctx, "error updating pm config to core", log.Fields{"device-id": dh.deviceID, "err": err})
326 }
Girish Gowdrae09a6202021-01-12 18:10:59 -0800327 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000328 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Debugw(ctx, "AdoptOrReconcileDevice: Agent/device init already done", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000330 }
331
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000332}
333
mpagenko057889c2021-01-21 16:51:58 +0000334func (dh *deviceHandler) processInterAdapterOMCIReceiveMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Himani Chawla26e555c2020-08-31 12:30:20 +0530335 msgBody := msg.GetBody()
336 omciMsg := &ic.InterAdapterOmciMessage{}
337 if err := ptypes.UnmarshalAny(msgBody, omciMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 logger.Warnw(ctx, "cannot-unmarshal-omci-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530339 "device-id": dh.deviceID, "error": err})
340 return err
341 }
342
mpagenko80622a52021-02-09 16:53:23 +0000343 /* 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 +0530344 //assuming omci message content is hex coded!
345 // with restricted output of 16(?) bytes would be ...omciMsg.Message[:16]
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 logger.Debugw(ctx, "inter-adapter-recv-omci", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530347 "device-id": dh.deviceID, "RxOmciMessage": hex.EncodeToString(omciMsg.Message)})
mpagenko80622a52021-02-09 16:53:23 +0000348 */
dbainbri4d3a0dc2020-12-02 00:33:42 +0000349 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Himani Chawla26e555c2020-08-31 12:30:20 +0530350 if pDevEntry != nil {
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000351 if pDevEntry.PDevOmciCC != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 return pDevEntry.PDevOmciCC.receiveMessage(log.WithSpanFromContext(context.TODO(), ctx), omciMsg.Message)
Holger Hildebrandt2fb70892020-10-28 11:53:18 +0000353 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 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 +0530355 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000356 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000357 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530358}
359
Himani Chawla6d2ae152020-09-02 13:11:20 +0530360func (dh *deviceHandler) processInterAdapterTechProfileDownloadReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000361 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530362 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000363
dbainbri4d3a0dc2020-12-02 00:33:42 +0000364 logger.Infow(ctx, "tech-profile-download-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000365
dbainbri4d3a0dc2020-12-02 00:33:42 +0000366 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000367 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000368 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000369 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
370 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530371 if dh.pOnuTP == nil {
372 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000373 logger.Errorw(ctx, "onuTechProf instance not set up for DLMsg request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530374 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000375 return fmt.Errorf("techProfile DLMsg request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530376 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000377 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000378 logger.Errorw(ctx, "TechProf-set rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000379 "device-state": dh.getDeviceReasonString()})
380 return fmt.Errorf("improper device state %s on device %s", dh.getDeviceReasonString(), dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530381 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000382 //previous state test here was just this one, now extended for more states to reject the SetRequest:
383 // at least 'mib-downloaded' should be reached for processing of this specific ONU configuration
384 // if (dh.deviceReason == "stopping-openomci") || (dh.deviceReason == "omci-admin-lock")
Himani Chawla26e555c2020-08-31 12:30:20 +0530385
386 msgBody := msg.GetBody()
387 techProfMsg := &ic.InterAdapterTechProfileDownloadMessage{}
388 if err := ptypes.UnmarshalAny(msgBody, techProfMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000389 logger.Warnw(ctx, "cannot-unmarshal-techprof-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530390 "device-id": dh.deviceID, "error": err})
391 return err
392 }
393
394 // we have to lock access to TechProfile processing based on different messageType calls or
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000395 // even to fast subsequent calls of the same messageType as well as OnuKVStore processing due
396 // to possible concurrent access by flow processing
Himani Chawla26e555c2020-08-31 12:30:20 +0530397 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000398 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000399
400 if techProfMsg.UniId > 255 {
401 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
402 techProfMsg.UniId, dh.deviceID))
403 }
404 uniID := uint8(techProfMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800405 tpID, err := GetTpIDFromTpPath(techProfMsg.Path)
406 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000407 logger.Errorw(ctx, "error-parsing-tpid-from-tppath", log.Fields{"err": err, "tp-path": techProfMsg.Path})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800408 return err
409 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000410
dbainbri4d3a0dc2020-12-02 00:33:42 +0000411 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, uint8(tpID), techProfMsg.Path); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530412 // if there has been some change for some uni TechProfilePath
413 //in order to allow concurrent calls to other dh instances we do not wait for execution here
414 //but doing so we can not indicate problems to the caller (who does what with that then?)
415 //by now we just assume straightforward successful execution
416 //TODO!!! Generally: In this scheme it would be good to have some means to indicate
417 // possible problems to the caller later autonomously
418
419 // deadline context to ensure completion of background routines waited for
420 //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 +0530421 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530422 dctx, cancel := context.WithDeadline(context.Background(), deadline)
423
Girish Gowdra041dcb32020-11-16 16:54:30 -0800424 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000425 pDevEntry.resetKvProcessingErrorIndication()
426
Himani Chawla26e555c2020-08-31 12:30:20 +0530427 var wg sync.WaitGroup
428 wg.Add(2) // for the 2 go routines to finish
429 // attention: deadline completion check and wg.Done is to be done in both routines
dbainbri4d3a0dc2020-12-02 00:33:42 +0000430 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniID, techProfMsg.Path, &wg)
431 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
432 dh.waitForCompletion(ctx, cancel, &wg, "TechProfDwld") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000433
Girish Gowdra041dcb32020-11-16 16:54:30 -0800434 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530435 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000436 // no change, nothing really to do - return success
Himani Chawla26e555c2020-08-31 12:30:20 +0530437 return nil
438}
439
Himani Chawla6d2ae152020-09-02 13:11:20 +0530440func (dh *deviceHandler) processInterAdapterDeleteGemPortReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000441 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530442 msg *ic.InterAdapterMessage) error {
443
dbainbri4d3a0dc2020-12-02 00:33:42 +0000444 logger.Infow(ctx, "delete-gem-port-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000445
dbainbri4d3a0dc2020-12-02 00:33:42 +0000446 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000447 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000448 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000449 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
450 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530451 if dh.pOnuTP == nil {
452 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000453 logger.Warnw(ctx, "onuTechProf instance not set up for DelGem request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530454 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000455 return fmt.Errorf("techProfile DelGem request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530456 }
457
458 msgBody := msg.GetBody()
459 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{}
460 if err := ptypes.UnmarshalAny(msgBody, delGemPortMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000461 logger.Warnw(ctx, "cannot-unmarshal-delete-gem-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530462 "device-id": dh.deviceID, "error": err})
463 return err
464 }
465
466 //compare TECH_PROFILE_DOWNLOAD_REQUEST
467 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000468 defer dh.pOnuTP.unlockTpProcMutex()
Himani Chawla26e555c2020-08-31 12:30:20 +0530469
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000470 if delGemPortMsg.UniId > 255 {
471 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
472 delGemPortMsg.UniId, dh.deviceID))
473 }
474 uniID := uint8(delGemPortMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800475 tpID, err := GetTpIDFromTpPath(delGemPortMsg.TpPath)
476 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 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 -0800478 return err
479 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530480
mpagenkofc4f56e2020-11-04 17:17:49 +0000481 //a removal of some GemPort would never remove the complete TechProfile entry (done on T-Cont)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000482
mpagenkofc4f56e2020-11-04 17:17:49 +0000483 // deadline context to ensure completion of background routines waited for
484 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
485 dctx, cancel := context.WithDeadline(context.Background(), deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000486
Girish Gowdra041dcb32020-11-16 16:54:30 -0800487 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000488
mpagenkofc4f56e2020-11-04 17:17:49 +0000489 var wg sync.WaitGroup
490 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delGemPortMsg.TpPath,
mpagenkofc4f56e2020-11-04 17:17:49 +0000492 cResourceGemPort, delGemPortMsg.GemPortId, &wg)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 dh.waitForCompletion(ctx, cancel, &wg, "GemDelete") //wait for background process to finish
mpagenkofc4f56e2020-11-04 17:17:49 +0000494
Girish Gowdra041dcb32020-11-16 16:54:30 -0800495 return dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530496}
497
Himani Chawla6d2ae152020-09-02 13:11:20 +0530498func (dh *deviceHandler) processInterAdapterDeleteTcontReqMessage(
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 ctx context.Context,
Himani Chawla26e555c2020-08-31 12:30:20 +0530500 msg *ic.InterAdapterMessage) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000501
dbainbri4d3a0dc2020-12-02 00:33:42 +0000502 logger.Infow(ctx, "delete-tcont-request", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000503
dbainbri4d3a0dc2020-12-02 00:33:42 +0000504 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000505 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000507 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
508 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530509 if dh.pOnuTP == nil {
510 //should normally not happen ...
dbainbri4d3a0dc2020-12-02 00:33:42 +0000511 logger.Warnw(ctx, "onuTechProf instance not set up for DelTcont request - ignoring request",
Himani Chawla26e555c2020-08-31 12:30:20 +0530512 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000513 return fmt.Errorf("techProfile DelTcont request while onuTechProf instance not setup: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +0530514 }
515
516 msgBody := msg.GetBody()
517 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{}
518 if err := ptypes.UnmarshalAny(msgBody, delTcontMsg); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000519 logger.Warnw(ctx, "cannot-unmarshal-delete-tcont-msg-body", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +0530520 "device-id": dh.deviceID, "error": err})
521 return err
522 }
523
524 //compare TECH_PROFILE_DOWNLOAD_REQUEST
525 dh.pOnuTP.lockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000526 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000527
528 if delTcontMsg.UniId > 255 {
529 return fmt.Errorf(fmt.Sprintf("received UniId value exceeds range: %d, device-id: %s",
530 delTcontMsg.UniId, dh.deviceID))
531 }
532 uniID := uint8(delTcontMsg.UniId)
Girish Gowdra041dcb32020-11-16 16:54:30 -0800533 tpPath := delTcontMsg.TpPath
534 tpID, err := GetTpIDFromTpPath(tpPath)
535 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 logger.Errorw(ctx, "error-extracting-tp-id-from-tp-path", log.Fields{"err": err, "tp-path": tpPath})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800537 return err
538 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000539
dbainbri4d3a0dc2020-12-02 00:33:42 +0000540 if bTpModify := pDevEntry.updateOnuUniTpPath(ctx, uniID, tpID, ""); bTpModify {
Himani Chawla26e555c2020-08-31 12:30:20 +0530541 // deadline context to ensure completion of background routines waited for
Himani Chawlad96df182020-09-28 11:12:02 +0530542 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
Himani Chawla26e555c2020-08-31 12:30:20 +0530543 dctx, cancel := context.WithDeadline(context.Background(), deadline)
544
Girish Gowdra041dcb32020-11-16 16:54:30 -0800545 dh.pOnuTP.resetTpProcessingErrorIndication(uniID, tpID)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000546 pDevEntry.resetKvProcessingErrorIndication()
547
Himani Chawla26e555c2020-08-31 12:30:20 +0530548 var wg sync.WaitGroup
549 wg.Add(2) // for the 2 go routines to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000550 go dh.pOnuTP.deleteTpResource(log.WithSpanFromContext(dctx, ctx), uniID, tpID, delTcontMsg.TpPath,
Himani Chawla26e555c2020-08-31 12:30:20 +0530551 cResourceTcont, delTcontMsg.AllocId, &wg)
552 // Removal of the tcont/alloc id mapping represents the removal of the tech profile
dbainbri4d3a0dc2020-12-02 00:33:42 +0000553 go pDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
554 dh.waitForCompletion(ctx, cancel, &wg, "TContDelete") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000555
Girish Gowdra041dcb32020-11-16 16:54:30 -0800556 return dh.combineErrorStrings(dh.pOnuTP.getTpProcessingErrorIndication(uniID, tpID), pDevEntry.getKvProcessingErrorIndication())
Himani Chawla26e555c2020-08-31 12:30:20 +0530557 }
Himani Chawla26e555c2020-08-31 12:30:20 +0530558 return nil
559}
560
Himani Chawla6d2ae152020-09-02 13:11:20 +0530561//processInterAdapterMessage sends the proxied messages to the target device
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000562// If the proxy address is not found in the unmarshalled message, it first fetches the onu device for which the message
563// is meant, and then send the unmarshalled omci message to this onu
dbainbri4d3a0dc2020-12-02 00:33:42 +0000564func (dh *deviceHandler) processInterAdapterMessage(ctx context.Context, msg *ic.InterAdapterMessage) error {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000565 msgID := msg.Header.Id
566 msgType := msg.Header.Type
567 fromTopic := msg.Header.FromTopic
568 toTopic := msg.Header.ToTopic
569 toDeviceID := msg.Header.ToDeviceId
570 proxyDeviceID := msg.Header.ProxyDeviceId
dbainbri4d3a0dc2020-12-02 00:33:42 +0000571 logger.Debugw(ctx, "InterAdapter message header", log.Fields{"msgID": msgID, "msgType": msgType,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000572 "fromTopic": fromTopic, "toTopic": toTopic, "toDeviceID": toDeviceID, "proxyDeviceID": proxyDeviceID})
573
574 switch msgType {
Holger Hildebrandt6c1fb0a2020-11-25 15:41:01 +0000575 // case ic.InterAdapterMessageType_ONU_IND_REQUEST: was handled by OpenONUAC already - see comments there
mpagenko057889c2021-01-21 16:51:58 +0000576 //OMCI_RESPONSE also accepted acc. to VOL-3756 (OMCI_REQUEST request was legacy code)
577 case ic.InterAdapterMessageType_OMCI_RESPONSE, ic.InterAdapterMessageType_OMCI_REQUEST:
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000578 {
mpagenko057889c2021-01-21 16:51:58 +0000579 return dh.processInterAdapterOMCIReceiveMessage(ctx, msg)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000580 }
mpagenkoaf801632020-07-03 10:00:42 +0000581 case ic.InterAdapterMessageType_TECH_PROFILE_DOWNLOAD_REQUEST:
582 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000583 return dh.processInterAdapterTechProfileDownloadReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000584 }
585 case ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST:
586 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000587 return dh.processInterAdapterDeleteGemPortReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000588
mpagenkoaf801632020-07-03 10:00:42 +0000589 }
590 case ic.InterAdapterMessageType_DELETE_TCONT_REQUEST:
591 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000592 return dh.processInterAdapterDeleteTcontReqMessage(ctx, msg)
mpagenkoaf801632020-07-03 10:00:42 +0000593 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000594 default:
595 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000596 logger.Errorw(ctx, "inter-adapter-unhandled-type", log.Fields{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000597 "msgType": msg.Header.Type, "device-id": dh.deviceID})
598 return fmt.Errorf("inter-adapter-unhandled-type: %d, %s", msg.Header.Type, dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000599 }
600 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000601}
602
mpagenkodff5dda2020-08-28 11:52:01 +0000603//FlowUpdateIncremental removes and/or adds the flow changes on a given device
dbainbri4d3a0dc2020-12-02 00:33:42 +0000604func (dh *deviceHandler) FlowUpdateIncremental(ctx context.Context,
605 apOfFlowChanges *openflow_13.FlowChanges,
mpagenkodff5dda2020-08-28 11:52:01 +0000606 apOfGroupChanges *openflow_13.FlowGroupChanges, apFlowMetaData *voltha.FlowMetadata) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000607 logger.Debugw(ctx, "FlowUpdateIncremental started", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000608
mpagenko01e726e2020-10-23 09:45:29 +0000609 var retError error = nil
610 //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 +0000611 if apOfFlowChanges.ToRemove != nil {
612 for _, flowItem := range apOfFlowChanges.ToRemove.Items {
mpagenkodff5dda2020-08-28 11:52:01 +0000613 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000614 logger.Warnw(ctx, "flow-remove no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000615 "device-id": dh.deviceID})
616 retError = fmt.Errorf("flow-remove no cookie, device-id %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000617 continue
618 }
619 flowInPort := flow.GetInPort(flowItem)
620 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 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 +0000622 retError = fmt.Errorf("flow-remove inPort invalid, device-id %s", dh.deviceID)
623 continue
624 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +0000625 } else if flowInPort == dh.ponPortNumber {
mpagenko01e726e2020-10-23 09:45:29 +0000626 //this is some downstream flow, not regarded as error, just ignored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000627 logger.Debugw(ctx, "flow-remove for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000628 "device-id": dh.deviceID, "inPort": flowInPort})
mpagenkodff5dda2020-08-28 11:52:01 +0000629 continue
630 } else {
631 // this is the relevant upstream flow
Himani Chawla6d2ae152020-09-02 13:11:20 +0530632 var loUniPort *onuUniPort
mpagenkodff5dda2020-08-28 11:52:01 +0000633 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
634 loUniPort = uniPort
635 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000636 logger.Warnw(ctx, "flow-remove inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000637 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
638 retError = fmt.Errorf("flow-remove inPort not found in UniPorts, inPort %d, device-id %s",
639 flowInPort, dh.deviceID)
640 continue
mpagenkodff5dda2020-08-28 11:52:01 +0000641 }
642 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000643 logger.Debugw(ctx, "flow-remove port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000644 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
mpagenkodff5dda2020-08-28 11:52:01 +0000645 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 err := dh.removeFlowItemFromUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000647 //try next flow after processing error
mpagenkodff5dda2020-08-28 11:52:01 +0000648 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000649 logger.Warnw(ctx, "flow-remove processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000650 log.Fields{"device-id": dh.deviceID, "error": err})
651 retError = err
652 continue
653 //return err
654 } else { // if last setting succeeds, overwrite possibly previously set error
655 retError = nil
mpagenkodff5dda2020-08-28 11:52:01 +0000656 }
657 }
658 }
659 }
mpagenko01e726e2020-10-23 09:45:29 +0000660 if apOfFlowChanges.ToAdd != nil {
661 for _, flowItem := range apOfFlowChanges.ToAdd.Items {
662 if flowItem.GetCookie() == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000663 logger.Debugw(ctx, "incremental flow-add no cookie: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000664 "device-id": dh.deviceID})
665 retError = fmt.Errorf("flow-add no cookie, device-id %s", dh.deviceID)
666 continue
667 }
668 flowInPort := flow.GetInPort(flowItem)
669 if flowInPort == uint32(of.OfpPortNo_OFPP_INVALID) {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 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 +0000671 retError = fmt.Errorf("flow-add inPort invalid, device-id %s", dh.deviceID)
672 continue
673 //return fmt.Errorf("flow inPort invalid: %s", dh.deviceID)
674 } else if flowInPort == dh.ponPortNumber {
675 //this is some downstream flow
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Debugw(ctx, "flow-add for downstream: ignore and continuing on checking further flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000677 "device-id": dh.deviceID, "inPort": flowInPort})
678 continue
679 } else {
680 // this is the relevant upstream flow
681 var loUniPort *onuUniPort
682 if uniPort, exist := dh.uniEntityMap[flowInPort]; exist {
683 loUniPort = uniPort
684 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Warnw(ctx, "flow-add inPort not found in UniPorts: ignore and continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000686 log.Fields{"device-id": dh.deviceID, "inPort": flowInPort})
687 retError = fmt.Errorf("flow-add inPort not found in UniPorts, inPort %d, device-id %s",
688 flowInPort, dh.deviceID)
689 continue
690 //return fmt.Errorf("flow-parameter inPort %d not found in internal UniPorts", flowInPort)
691 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000692 // let's still assume that we receive the flow-add only in some 'active' device state (as so far observed)
693 // if not, we just throw some error here to have an indication about that, if we really need to support that
694 // then we would need to create some means to activate the internal stored flows
695 // after the device gets active automatically (and still with its dependency to the TechProfile)
696 // for state checking compare also code here: processInterAdapterTechProfileDownloadReqMessage
697 // also abort for the other still possible flows here
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000698 if !dh.isReadyForOmciConfig() {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 logger.Errorw(ctx, "flow-add rejected: improper device state", log.Fields{"device-id": dh.deviceID,
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000700 "last device-reason": dh.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +0000701 return fmt.Errorf("improper device state on device %s", dh.deviceID)
702 }
703
mpagenko01e726e2020-10-23 09:45:29 +0000704 flowOutPort := flow.GetOutPort(flowItem)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000705 logger.Debugw(ctx, "flow-add port indications", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000706 "device-id": dh.deviceID, "inPort": flowInPort, "outPort": flowOutPort,
707 "uniPortName": loUniPort.name})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000708 err := dh.addFlowItemToUniPort(ctx, flowItem, loUniPort)
mpagenko01e726e2020-10-23 09:45:29 +0000709 //try next flow after processing error
710 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 logger.Warnw(ctx, "flow-add processing error: continuing on checking further flows",
mpagenko01e726e2020-10-23 09:45:29 +0000712 log.Fields{"device-id": dh.deviceID, "error": err})
713 retError = err
714 continue
715 //return err
716 } else { // if last setting succeeds, overwrite possibly previously set error
717 retError = nil
718 }
719 }
720 }
721 }
722 return retError
mpagenkodff5dda2020-08-28 11:52:01 +0000723}
724
Himani Chawla6d2ae152020-09-02 13:11:20 +0530725//disableDevice locks the ONU and its UNI/VEIP ports (admin lock via OMCI)
mpagenkofc4f56e2020-11-04 17:17:49 +0000726//following are the expected device states after this activity:
727//Device Admin-State : down (on rwCore), Port-State: UNKNOWN, Conn-State: REACHABLE, Reason: omci-admin-lock
728// (Conn-State: REACHABLE might conflict with some previous ONU Down indication - maybe to be resolved later)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000729func (dh *deviceHandler) disableDevice(ctx context.Context, device *voltha.Device) {
730 logger.Debugw(ctx, "disable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000731
mpagenko900ee4b2020-10-12 11:56:34 +0000732 //admin-lock reason can also be used uniquely for setting the DeviceState accordingly
mpagenkofc4f56e2020-11-04 17:17:49 +0000733 //note that disableDevice sequences in some 'ONU active' state may yield also
734 // "tech...delete-success" or "omci-flow-deleted" according to further received requests in the end
mpagenko900ee4b2020-10-12 11:56:34 +0000735 // - inblock state checking to prevent possibly unneeded processing (on command repitition)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000736 if dh.getDeviceReason() != drOmciAdminLock {
mpagenkofc4f56e2020-11-04 17:17:49 +0000737 //disable-device shall be just a UNi/ONU-G related admin state setting
738 //all other configurations/FSM's shall not be impacted and shall execute as required by the system
mpagenko900ee4b2020-10-12 11:56:34 +0000739
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000740 if dh.isReadyForOmciConfig() {
mpagenko01e726e2020-10-23 09:45:29 +0000741 // disable UNI ports/ONU
742 // *** should generate UniDisableStateDone event - used to disable the port(s) on success
743 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000744 dh.createUniLockFsm(ctx, true, UniDisableStateDone)
mpagenko01e726e2020-10-23 09:45:29 +0000745 } else { //LockStateFSM already init
746 dh.pLockStateFsm.setSuccessEvent(UniDisableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000747 dh.runUniLockFsm(ctx, true)
mpagenko01e726e2020-10-23 09:45:29 +0000748 }
749 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000750 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko01e726e2020-10-23 09:45:29 +0000751 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000752 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko01e726e2020-10-23 09:45:29 +0000753 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
754 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +0000755 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko01e726e2020-10-23 09:45:29 +0000756 }
mpagenko01e726e2020-10-23 09:45:29 +0000757 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
Holger Hildebrandt80129db2020-11-23 10:49:32 +0000758
759 //TODO with VOL-3045/VOL-3046: catch and return error, valid for all occurrences in the codebase
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko3af1f032020-06-10 08:53:41 +0000761 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300762 }
763}
764
Himani Chawla6d2ae152020-09-02 13:11:20 +0530765//reEnableDevice unlocks the ONU and its UNI/VEIP ports (admin unlock via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000766func (dh *deviceHandler) reEnableDevice(ctx context.Context, device *voltha.Device) {
767 logger.Debugw(ctx, "reenable-device", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko3af1f032020-06-10 08:53:41 +0000768
mpagenkofc4f56e2020-11-04 17:17:49 +0000769 //setting ReadyForSpecificOmciConfig here is just a workaround for BBSIM testing in the sequence
770 // OnuSoftReboot-disable-enable, because BBSIM does not generate a new OnuIndication-Up event after SoftReboot
771 // which is the assumption for real ONU's, where the ready-state is then set according to the following MibUpload/Download
772 // for real ONU's that should have nearly no influence
773 // Note that for real ONU's there is anyway a problematic situation with following sequence:
774 // OnuIndication-Dw (or not active at all) (- disable) - enable: here already the LockFsm may run into timeout (no OmciResponse)
775 // but that anyway is hopefully resolved by some OnuIndication-Up event (maybe to be tested)
776 // one could also argue, that a device-enable should also enable attempts for specific omci configuration
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000777 dh.setReadyForOmciConfig(true) //needed to allow subsequent flow/techProf config (on BBSIM)
mpagenkofc4f56e2020-11-04 17:17:49 +0000778
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000779 // enable ONU/UNI ports
mpagenko900ee4b2020-10-12 11:56:34 +0000780 // *** should generate UniEnableStateDone event - used to disable the port(s) on success
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000781 if dh.pUnlockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000782 dh.createUniLockFsm(ctx, false, UniEnableStateDone)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000783 } else { //UnlockStateFSM already init
mpagenko900ee4b2020-10-12 11:56:34 +0000784 dh.pUnlockStateFsm.setSuccessEvent(UniEnableStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785 dh.runUniLockFsm(ctx, false)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +0000786 }
ozgecanetsiafce57b12020-05-25 14:39:35 +0300787}
788
dbainbri4d3a0dc2020-12-02 00:33:42 +0000789func (dh *deviceHandler) reconcileDeviceOnuInd(ctx context.Context) {
790 logger.Debugw(ctx, "reconciling - simulate onu indication", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000791
dbainbri4d3a0dc2020-12-02 00:33:42 +0000792 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000793 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000794 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000795 return
796 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797 if err := pDevEntry.restoreDataFromOnuKvStore(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
mpagenko2418ab02020-11-12 12:58:06 +0000798 if err == fmt.Errorf("no-ONU-data-found") {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "no persistent data found - abort reconciling", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000800 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000801 logger.Errorw(ctx, "reconciling - restoring OnuTp-data failed - abort", log.Fields{"err": err, "device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000802 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000803 dh.stopReconciling(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000804 return
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000805 }
Himani Chawla4d908332020-08-31 12:30:20 +0530806 var onuIndication oop.OnuIndication
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000807 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000808 onuIndication.IntfId = pDevEntry.sOnuPersistentData.PersIntfID
809 onuIndication.OnuId = pDevEntry.sOnuPersistentData.PersOnuID
810 onuIndication.OperState = pDevEntry.sOnuPersistentData.PersOperState
811 onuIndication.AdminState = pDevEntry.sOnuPersistentData.PersAdminState
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000812 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000813 _ = dh.createInterface(ctx, &onuIndication)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000814}
815
dbainbri4d3a0dc2020-12-02 00:33:42 +0000816func (dh *deviceHandler) reconcileDeviceTechProf(ctx context.Context) {
817 logger.Debugw(ctx, "reconciling - trigger tech profile config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000818
dbainbri4d3a0dc2020-12-02 00:33:42 +0000819 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000820 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000821 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000822 if !dh.isSkipOnuConfigReconciling() {
823 dh.stopReconciling(ctx)
824 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000825 return
826 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000827 dh.pOnuTP.lockTpProcMutex()
828 defer dh.pOnuTP.unlockTpProcMutex()
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000829 pDevEntry.mutexPersOnuConfig.RLock()
830 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000831
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000832 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000833 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000834 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000835 if !dh.isSkipOnuConfigReconciling() {
836 dh.stopReconciling(ctx)
837 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000838 return
839 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000840 techProfsFound := false
841 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000842 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000843 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
844 if len(uniData.PersTpPathMap) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000845 logger.Debugw(ctx, "reconciling - no TPs stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000846 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000847 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000848 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000849 techProfsFound = true
Girish Gowdra041dcb32020-11-16 16:54:30 -0800850 for tpID := range uniData.PersTpPathMap {
851 // deadline context to ensure completion of background routines waited for
852 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
853 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000855
Girish Gowdra041dcb32020-11-16 16:54:30 -0800856 dh.pOnuTP.resetTpProcessingErrorIndication(uniData.PersUniID, tpID)
857 var wg sync.WaitGroup
858 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 go dh.pOnuTP.configureUniTp(log.WithSpanFromContext(dctx, ctx), uniData.PersUniID, uniData.PersTpPathMap[tpID], &wg)
860 dh.waitForCompletion(ctx, cancel, &wg, "TechProfReconcile") //wait for background process to finish
Girish Gowdra041dcb32020-11-16 16:54:30 -0800861 if err := dh.pOnuTP.getTpProcessingErrorIndication(uniData.PersUniID, tpID); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Girish Gowdra041dcb32020-11-16 16:54:30 -0800863 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000864 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000865 if len(uniData.PersFlowParams) != 0 {
866 flowsFound = true
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000867 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000868 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000869 if !techProfsFound {
870 logger.Debugw(ctx, "reconciling - no TPs have been stored before adapter restart - terminate reconcilement",
871 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000872 if !dh.isSkipOnuConfigReconciling() {
873 dh.stopReconciling(ctx)
874 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000875 return
876 }
877 if dh.isSkipOnuConfigReconciling() {
878 dh.setDeviceReason(drTechProfileConfigDownloadSuccess)
879 }
880 if !flowsFound {
881 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
882 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000883 if !dh.isSkipOnuConfigReconciling() {
884 dh.stopReconciling(ctx)
885 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000886 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000887}
888
dbainbri4d3a0dc2020-12-02 00:33:42 +0000889func (dh *deviceHandler) reconcileDeviceFlowConfig(ctx context.Context) {
890 logger.Debugw(ctx, "reconciling - trigger flow config", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000891
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000893 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000894 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000895 if !dh.isSkipOnuConfigReconciling() {
896 dh.stopReconciling(ctx)
897 }
Holger Hildebrandtf41a1602020-08-19 09:52:50 +0000898 return
899 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000900 pDevEntry.mutexPersOnuConfig.RLock()
901 defer pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000902
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000903 if len(pDevEntry.sOnuPersistentData.PersUniConfig) == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000904 logger.Debugw(ctx, "reconciling - no uni-configs have been stored before adapter restart - terminate reconcilement",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000905 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000906 if !dh.isSkipOnuConfigReconciling() {
907 dh.stopReconciling(ctx)
908 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000909 return
910 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000911 flowsFound := false
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000912 for _, uniData := range pDevEntry.sOnuPersistentData.PersUniConfig {
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000913 //TODO: check for uni-port specific reconcilement in case of multi-uni-port-per-onu-support
914 if len(uniData.PersFlowParams) == 0 {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000915 logger.Debugw(ctx, "reconciling - no flows stored for uniID",
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000916 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000917 continue
918 }
919 if len(uniData.PersTpPathMap) == 0 {
920 logger.Warnw(ctx, "reconciling - flows but no TPs stored for uniID",
921 log.Fields{"uni-id": uniData.PersUniID, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000922 // It doesn't make sense to configure any flows if no TPs are available
923 continue
Holger Hildebrandt3a644642020-12-02 09:46:18 +0000924 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000925 var uniPort *onuUniPort
926 var exist bool
dbainbri4d3a0dc2020-12-02 00:33:42 +0000927 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(), uint32(uniData.PersUniID))
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000928 if uniPort, exist = dh.uniEntityMap[uniNo]; !exist {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000929 logger.Errorw(ctx, "reconciling - onuUniPort data not found - terminate reconcilement",
930 log.Fields{"uniNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000931 if !dh.isSkipOnuConfigReconciling() {
932 dh.stopReconciling(ctx)
933 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000934 return
935 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000936 flowsFound = true
937 flowsProcessed := 0
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000938 dh.setReconcilingFlows(true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000939 for _, flowData := range uniData.PersFlowParams {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000940 logger.Debugw(ctx, "reconciling - add flow with cookie slice", log.Fields{"device-id": dh.deviceID, "cookies": flowData.CookieSlice})
mpagenko01e726e2020-10-23 09:45:29 +0000941 //the slice can be passed 'by value' here, - which internally passes its reference copy
mpagenkof1fc3862021-02-16 10:09:52 +0000942 dh.lockVlanConfig.RLock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000943 if _, exist = dh.UniVlanConfigFsmMap[uniData.PersUniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000944 if err := dh.UniVlanConfigFsmMap[uniData.PersUniID].SetUniFlowParams(ctx, flowData.VlanRuleParams.TpID,
mpagenko01e726e2020-10-23 09:45:29 +0000945 flowData.CookieSlice, uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
946 uint8(flowData.VlanRuleParams.SetPcp)); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000947 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000948 }
mpagenkof1fc3862021-02-16 10:09:52 +0000949 dh.lockVlanConfig.RUnlock()
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000950 } else {
mpagenkof1fc3862021-02-16 10:09:52 +0000951 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000952 if err := dh.createVlanFilterFsm(ctx, uniPort, flowData.VlanRuleParams.TpID, flowData.CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000953 uint16(flowData.VlanRuleParams.MatchVid), uint16(flowData.VlanRuleParams.SetVid),
mpagenkofc4f56e2020-11-04 17:17:49 +0000954 uint8(flowData.VlanRuleParams.SetPcp), OmciVlanFilterAddDone); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000955 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000956 }
957 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000958 flowsProcessed++
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000959 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000960 logger.Debugw(ctx, "reconciling - flows processed", log.Fields{"device-id": dh.deviceID, "flowsProcessed": flowsProcessed,
961 "numUniFlows": dh.UniVlanConfigFsmMap[uniData.PersUniID].numUniFlows,
962 "configuredUniFlow": dh.UniVlanConfigFsmMap[uniData.PersUniID].configuredUniFlow})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000963 dh.setReconcilingFlows(false)
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000964 }
965 if !flowsFound {
966 logger.Debugw(ctx, "reconciling - no flows have been stored before adapter restart - terminate reconcilement",
967 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt7e9de862021-03-26 14:01:49 +0000968 if !dh.isSkipOnuConfigReconciling() {
969 dh.stopReconciling(ctx)
970 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000971 return
972 }
973 if dh.isSkipOnuConfigReconciling() {
974 dh.setDeviceReason(drOmciFlowsPushed)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000975 }
976}
977
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +0000978func (dh *deviceHandler) reconcileEnd(ctx context.Context) {
979 logger.Debugw(ctx, "reconciling - completed!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +0000980 dh.stopReconciling(ctx)
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000981}
982
dbainbri4d3a0dc2020-12-02 00:33:42 +0000983func (dh *deviceHandler) deleteDevicePersistencyData(ctx context.Context) error {
984 logger.Debugw(ctx, "delete device persistency data", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000985
dbainbri4d3a0dc2020-12-02 00:33:42 +0000986 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000987 if pDevEntry == nil {
mpagenko2418ab02020-11-12 12:58:06 +0000988 //IfDevEntry does not exist here, no problem - no persistent data should have been stored
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989 logger.Debugw(ctx, "OnuDevice does not exist - nothing to delete", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +0000990 return nil
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +0000991 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000992
993 // deadline context to ensure completion of background routines waited for
994 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
Himani Chawlad96df182020-09-28 11:12:02 +0530995 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
dbainbri4d3a0dc2020-12-02 00:33:42 +0000996 dctx, cancel := context.WithDeadline(ctx, deadline)
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000997
998 pDevEntry.resetKvProcessingErrorIndication()
999
1000 var wg sync.WaitGroup
1001 wg.Add(1) // for the 1 go routine to finish
dbainbri4d3a0dc2020-12-02 00:33:42 +00001002 go pDevEntry.deleteDataFromOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
1003 dh.waitForCompletion(ctx, cancel, &wg, "DeleteDevice") //wait for background process to finish
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001004
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001005 // TODO: further actions - stop metrics and FSMs, remove device ...
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001006 return pDevEntry.getKvProcessingErrorIndication()
Holger Hildebrandt9ca8b132020-08-07 14:45:03 +00001007}
1008
mpagenko15ff4a52021-03-02 10:09:20 +00001009//func (dh *deviceHandler) rebootDevice(ctx context.Context, device *voltha.Device) error {
1010// before this change here return like this was used:
1011// return fmt.Errorf("device-unreachable: %s, %s", dh.deviceID, device.SerialNumber)
1012//was and is called in background - error return does not make sense
1013func (dh *deviceHandler) rebootDevice(ctx context.Context, aCheckDeviceState bool, device *voltha.Device) {
1014 logger.Infow(ctx, "reboot-device", log.Fields{"device-id": dh.deviceID, "SerialNumber": dh.device.SerialNumber})
1015 if aCheckDeviceState && device.ConnectStatus != voltha.ConnectStatus_REACHABLE {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001016 logger.Errorw(ctx, "device-unreachable", log.Fields{"device-id": device.Id, "SerialNumber": device.SerialNumber})
mpagenko15ff4a52021-03-02 10:09:20 +00001017 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001018 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001019 if err := dh.pOnuOmciDevice.reboot(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301020 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001021 logger.Errorw(ctx, "error-rebooting-device", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001022 return
Himani Chawla4d908332020-08-31 12:30:20 +05301023 }
mpagenko01e726e2020-10-23 09:45:29 +00001024
1025 //transfer the possibly modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001026 dh.disableUniPortStateUpdate(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001027
dbainbri4d3a0dc2020-12-02 00:33:42 +00001028 logger.Debugw(ctx, "call DeviceStateUpdate upon reboot", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001029 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001030 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
ozgecanetsiae11479f2020-07-06 09:44:47 +03001031 voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001032 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001033 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko15ff4a52021-03-02 10:09:20 +00001034 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001035 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001036 if err := dh.deviceReasonUpdate(ctx, drRebooting, true); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +00001037 return
ozgecanetsiae11479f2020-07-06 09:44:47 +03001038 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001039 dh.setReadyForOmciConfig(false)
mpagenko8b07c1b2020-11-26 10:36:31 +00001040 //no specific activity to synchronize any internal FSM to the 'rebooted' state is explicitly done here
1041 // the expectation ids for a real device, that it will be synced with the expected following 'down' indication
1042 // as BBSIM does not support this testing requires explicite disable/enable device calls in which sequence also
1043 // all other FSM's should be synchronized again
ozgecanetsiae11479f2020-07-06 09:44:47 +03001044}
1045
mpagenkoc8bba412021-01-15 15:38:44 +00001046//doOnuSwUpgrade initiates the SW download transfer to the ONU and on success activates the (inactive) image
mpagenko80622a52021-02-09 16:53:23 +00001047func (dh *deviceHandler) doOnuSwUpgrade(ctx context.Context, apImageDsc *voltha.ImageDownload,
1048 apDownloadManager *adapterDownloadManager) error {
1049 logger.Debugw(ctx, "onuSwUpgrade requested", log.Fields{
mpagenkoc8bba412021-01-15 15:38:44 +00001050 "device-id": dh.deviceID, "image-name": (*apImageDsc).Name})
mpagenko80622a52021-02-09 16:53:23 +00001051
1052 var err error
mpagenko15ff4a52021-03-02 10:09:20 +00001053 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
1054 if pDevEntry == nil {
1055 logger.Errorw(ctx, "start Onu SW upgrade rejected: no valid OnuDevice", log.Fields{"device-id": dh.deviceID})
1056 return fmt.Errorf("start Onu SW upgrade rejected: no valid OnuDevice for device-id: %s", dh.deviceID)
1057 }
1058
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001059 if dh.isReadyForOmciConfig() {
mpagenko15ff4a52021-03-02 10:09:20 +00001060 var inactiveImageID uint16
1061 if inactiveImageID, err = pDevEntry.GetInactiveImageMeID(ctx); err == nil {
1062 dh.lockUpgradeFsm.Lock()
1063 defer dh.lockUpgradeFsm.Unlock()
1064 if dh.pOnuUpradeFsm == nil {
1065 err = dh.createOnuUpgradeFsm(ctx, pDevEntry, OmciOnuSwUpgradeDone)
1066 if err == nil {
1067 if err = dh.pOnuUpradeFsm.SetDownloadParams(ctx, inactiveImageID, apImageDsc, apDownloadManager); err != nil {
1068 logger.Errorw(ctx, "onu upgrade fsm could not set parameters", log.Fields{
1069 "device-id": dh.deviceID, "error": err})
1070 }
1071 } else {
1072 logger.Errorw(ctx, "onu upgrade fsm could not be created", log.Fields{
mpagenko80622a52021-02-09 16:53:23 +00001073 "device-id": dh.deviceID, "error": err})
1074 }
mpagenko15ff4a52021-03-02 10:09:20 +00001075 } else { //OnuSw upgrade already running - restart (with possible abort of running)
1076 logger.Debugw(ctx, "Onu SW upgrade already running - abort", log.Fields{"device-id": dh.deviceID})
1077 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1078 if pUpgradeStatemachine != nil {
1079 if err = pUpgradeStatemachine.Event(upgradeEvAbort); err != nil {
1080 logger.Errorw(ctx, "onu upgrade fsm could not abort a running processing", log.Fields{
1081 "device-id": dh.deviceID, "error": err})
1082 }
1083 err = fmt.Errorf("aborted Onu SW upgrade but not automatically started, try again, device-id: %s", dh.deviceID)
1084 //TODO!!!: wait for 'ready' to start and configure - see above SetDownloadParams()
1085 // for now a second start of download should work again
1086 } else { //should never occur
1087 logger.Errorw(ctx, "onu upgrade fsm inconsistent setup", log.Fields{
1088 "device-id": dh.deviceID})
1089 err = fmt.Errorf("onu upgrade fsm inconsistent setup, baseFsm invalid for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001090 }
mpagenko80622a52021-02-09 16:53:23 +00001091 }
mpagenko15ff4a52021-03-02 10:09:20 +00001092 } else {
1093 logger.Errorw(ctx, "start Onu SW upgrade rejected: no inactive image", log.Fields{
1094 "device-id": dh.deviceID, "error": err})
mpagenko80622a52021-02-09 16:53:23 +00001095 }
1096 } else {
mpagenko15ff4a52021-03-02 10:09:20 +00001097 logger.Errorw(ctx, "start Onu SW upgrade rejected: no active OMCI connection", log.Fields{"device-id": dh.deviceID})
1098 err = fmt.Errorf("start Onu SW upgrade rejected: no active OMCI connection for device-id: %s", dh.deviceID)
mpagenko80622a52021-02-09 16:53:23 +00001099 }
1100 return err
mpagenkoc8bba412021-01-15 15:38:44 +00001101}
1102
Himani Chawla6d2ae152020-09-02 13:11:20 +05301103// deviceHandler methods that implement the adapters interface requests## end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001104// #####################################################################################
1105
1106// ################ to be updated acc. needs of ONU Device ########################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301107// deviceHandler StateMachine related state transition methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001108
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109func (dh *deviceHandler) logStateChange(ctx context.Context, e *fsm.Event) {
1110 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 +00001111}
1112
1113// doStateInit provides the device update to the core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001114func (dh *deviceHandler) doStateInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001115
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 logger.Debug(ctx, "doStateInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001117 var err error
1118
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001119 // populate what we know. rest comes later after mib sync
1120 dh.device.Root = false
1121 dh.device.Vendor = "OpenONU"
1122 dh.device.Model = "go"
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001123 dh.device.Reason = deviceReasonMap[drActivatingOnu]
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001124 dh.setDeviceReason(drActivatingOnu)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001125
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001126 dh.logicalDeviceID = dh.deviceID // really needed - what for ??? //TODO!!!
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001127
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001128 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001129 logger.Infow(ctx, "DeviceUpdate", log.Fields{"deviceReason": dh.device.Reason, "device-id": dh.deviceID})
1130 _ = dh.coreProxy.DeviceUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.device)
Himani Chawlac07fda02020-12-09 16:21:21 +05301131 //TODO Need to Update Device Reason To CORE as part of device update userstory
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001132 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001133 logger.Debugw(ctx, "reconciling - don't notify core about DeviceUpdate",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001134 log.Fields{"device-id": dh.deviceID})
1135 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001136
Himani Chawla4d908332020-08-31 12:30:20 +05301137 dh.parentID = dh.device.ParentId
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001138 dh.ponPortNumber = dh.device.ParentPortNo
1139
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001140 // store proxy parameters for later communication - assumption: invariant, else they have to be requested dynamically!!
1141 dh.ProxyAddressID = dh.device.ProxyAddress.GetDeviceId()
1142 dh.ProxyAddressType = dh.device.ProxyAddress.GetDeviceType()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001143 logger.Debugw(ctx, "device-updated", log.Fields{"device-id": dh.deviceID, "proxyAddressID": dh.ProxyAddressID,
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001144 "proxyAddressType": dh.ProxyAddressType, "SNR": dh.device.SerialNumber,
Himani Chawla4d908332020-08-31 12:30:20 +05301145 "ParentId": dh.parentID, "ParentPortNo": dh.ponPortNumber})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001146
1147 /*
1148 self._pon = PonPort.create(self, self._pon_port_number)
1149 self._pon.add_peer(self.parent_id, self._pon_port_number)
1150 self.logger.debug('adding-pon-port-to-agent',
1151 type=self._pon.get_port().type,
1152 admin_state=self._pon.get_port().admin_state,
1153 oper_status=self._pon.get_port().oper_status,
1154 )
1155 */
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001156 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001157 logger.Debugw(ctx, "adding-pon-port", log.Fields{"device-id": dh.deviceID, "ponPortNo": dh.ponPortNumber})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001158 var ponPortNo uint32 = 1
1159 if dh.ponPortNumber != 0 {
1160 ponPortNo = dh.ponPortNumber
1161 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001162
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001163 pPonPort := &voltha.Port{
1164 PortNo: ponPortNo,
1165 Label: fmt.Sprintf("pon-%d", ponPortNo),
1166 Type: voltha.Port_PON_ONU,
1167 OperStatus: voltha.OperStatus_ACTIVE,
Himani Chawla4d908332020-08-31 12:30:20 +05301168 Peers: []*voltha.Port_PeerPort{{DeviceId: dh.parentID, // Peer device is OLT
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001169 PortNo: ponPortNo}}, // Peer port is parent's port number
1170 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 if err = dh.coreProxy.PortCreated(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, pPonPort); err != nil {
1172 logger.Fatalf(ctx, "Device FSM: PortCreated-failed-%s", err)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001173 e.Cancel(err)
1174 return
1175 }
1176 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 logger.Debugw(ctx, "reconciling - pon-port already added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001178 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001179 logger.Debug(ctx, "doStateInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001180}
1181
1182// postInit setups the DeviceEntry for the conerned device
dbainbri4d3a0dc2020-12-02 00:33:42 +00001183func (dh *deviceHandler) postInit(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001184
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185 logger.Debug(ctx, "postInit-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001186 var err error
1187 /*
1188 dh.Client = oop.NewOpenoltClient(dh.clientCon)
1189 dh.pTransitionMap.Handle(ctx, GrpcConnected)
1190 return nil
1191 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192 if err = dh.addOnuDeviceEntry(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
1193 logger.Fatalf(ctx, "Device FSM: addOnuDeviceEntry-failed-%s", err)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001194 e.Cancel(err)
1195 return
1196 }
1197
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001198 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001199 go dh.reconcileDeviceOnuInd(ctx)
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001200 // reconcilement will be continued after mib download is done
1201 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001202
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001203 /*
1204 ############################################################################
1205 # Setup Alarm handler
1206 self.events = AdapterEvents(self.core_proxy, device.id, self.logical_device_id,
1207 device.serial_number)
1208 ############################################################################
1209 # Setup PM configuration for this device
1210 # Pass in ONU specific options
1211 kwargs = {
1212 OnuPmMetrics.DEFAULT_FREQUENCY_KEY: OnuPmMetrics.DEFAULT_ONU_COLLECTION_FREQUENCY,
1213 'heartbeat': self.heartbeat,
1214 OnuOmciPmMetrics.OMCI_DEV_KEY: self._onu_omci_device
1215 }
1216 self.logger.debug('create-pm-metrics', device_id=device.id, serial_number=device.serial_number)
1217 self._pm_metrics = OnuPmMetrics(self.events, self.core_proxy, self.device_id,
1218 self.logical_device_id, device.serial_number,
1219 grouped=True, freq_override=False, **kwargs)
1220 pm_config = self._pm_metrics.make_proto()
1221 self._onu_omci_device.set_pm_config(self._pm_metrics.omci_pm.openomci_interval_pm)
1222 self.logger.info("initial-pm-config", device_id=device.id, serial_number=device.serial_number)
1223 yield self.core_proxy.device_pm_config_update(pm_config, init=True)
1224
1225 # Note, ONU ID and UNI intf set in add_uni_port method
1226 self._onu_omci_device.alarm_synchronizer.set_alarm_params(mgr=self.events,
1227 ani_ports=[self._pon])
1228
1229 # Code to Run OMCI Test Action
1230 kwargs_omci_test_action = {
1231 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1232 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1233 }
1234 serial_number = device.serial_number
1235 self._test_request = OmciTestRequest(self.core_proxy,
1236 self.omci_agent, self.device_id,
1237 AniG, serial_number,
1238 self.logical_device_id,
1239 exclusive=False,
1240 **kwargs_omci_test_action)
1241
1242 self.enabled = True
1243 else:
1244 self.logger.info('onu-already-activated')
1245 */
Girish Gowdrae09a6202021-01-12 18:10:59 -08001246
dbainbri4d3a0dc2020-12-02 00:33:42 +00001247 logger.Debug(ctx, "postInit-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001248}
1249
1250// doStateConnected get the device info and update to voltha core
1251// for comparison of the original method (not that easy to uncomment): compare here:
1252// voltha-openolt-adapter/adaptercore/device_handler.go
1253// -> this one obviously initiates all communication interfaces of the device ...?
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254func (dh *deviceHandler) doStateConnected(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001255
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Debug(ctx, "doStateConnected-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301257 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001258 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001259 logger.Debug(ctx, "doStateConnected-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001260}
1261
1262// doStateUp handle the onu up indication and update to voltha core
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263func (dh *deviceHandler) doStateUp(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001264
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265 logger.Debug(ctx, "doStateUp-started")
Himani Chawla4d908332020-08-31 12:30:20 +05301266 err := errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001267 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 logger.Debug(ctx, "doStateUp-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001269
1270 /*
1271 // Synchronous call to update device state - this method is run in its own go routine
1272 if err := dh.coreProxy.DeviceStateUpdate(ctx, dh.device.Id, voltha.ConnectStatus_REACHABLE,
1273 voltha.OperStatus_ACTIVE); err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001274 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 +00001275 return err
1276 }
1277 return nil
1278 */
1279}
1280
1281// doStateDown handle the onu down indication
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282func (dh *deviceHandler) doStateDown(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001283
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 logger.Debug(ctx, "doStateDown-started")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001285 var err error
1286
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001287 device := dh.device
1288 if device == nil {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001289 /*TODO: needs to handle error scenarios */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001290 logger.Errorw(ctx, "Failed to fetch handler device", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001291 e.Cancel(err)
1292 return
1293 }
1294
1295 cloned := proto.Clone(device).(*voltha.Device)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001296 logger.Debugw(ctx, "do-state-down", log.Fields{"ClonedDeviceID": cloned.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001297 /*
1298 // Update the all ports state on that device to disable
1299 if er := dh.coreProxy.PortsStateUpdate(ctx, cloned.Id, voltha.OperStatus_UNKNOWN); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001300 logger.Errorw("updating-ports-failed", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001301 return er
1302 }
1303
1304 //Update the device oper state and connection status
1305 cloned.OperStatus = voltha.OperStatus_UNKNOWN
1306 cloned.ConnectStatus = common.ConnectStatus_UNREACHABLE
1307 dh.device = cloned
1308
1309 if er := dh.coreProxy.DeviceStateUpdate(ctx, cloned.Id, cloned.ConnectStatus, cloned.OperStatus); er != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001310 logger.Errorw("error-updating-device-state", log.Fields{"device-id": device.Id, "error": er})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001311 return er
1312 }
1313
1314 //get the child device for the parent device
1315 onuDevices, err := dh.coreProxy.GetChildDevices(ctx, dh.device.Id)
1316 if err != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001317 logger.Errorw("failed to get child devices information", log.Fields{"device-id": dh.device.Id, "error": err})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001318 return err
1319 }
1320 for _, onuDevice := range onuDevices.Items {
1321
1322 // Update onu state as down in onu adapter
1323 onuInd := oop.OnuIndication{}
1324 onuInd.OperState = "down"
1325 er := dh.AdapterProxy.SendInterAdapterMessage(ctx, &onuInd, ic.InterAdapterMessageType_ONU_IND_REQUEST,
1326 "openolt", onuDevice.Type, onuDevice.Id, onuDevice.ProxyAddress.DeviceId, "")
1327 if er != nil {
1328 logger.Errorw("Failed to send inter-adapter-message", log.Fields{"OnuInd": onuInd,
mpagenko01e726e2020-10-23 09:45:29 +00001329 "From Adapter": "openolt", "DevieType": onuDevice.Type, "device-id": onuDevice.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001330 //Do not return here and continue to process other ONUs
1331 }
1332 }
1333 // * Discovered ONUs entries need to be cleared , since after OLT
1334 // is up, it starts sending discovery indications again* /
1335 dh.discOnus = sync.Map{}
mpagenko01e726e2020-10-23 09:45:29 +00001336 logger.Debugw("do-state-down-end", log.Fields{"device-id": device.Id})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001337 return nil
1338 */
Himani Chawla4d908332020-08-31 12:30:20 +05301339 err = errors.New("device FSM: function not implemented yet")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001340 e.Cancel(err)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 logger.Debug(ctx, "doStateDown-done")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001342}
1343
Himani Chawla6d2ae152020-09-02 13:11:20 +05301344// deviceHandler StateMachine related state transition methods ##### end #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001345// #################################################################################
1346
1347// ###################################################
Himani Chawla6d2ae152020-09-02 13:11:20 +05301348// deviceHandler utility methods ##### begin #########
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001349
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001350//getOnuDeviceEntry gets the ONU device entry and may wait until its value is defined
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351func (dh *deviceHandler) getOnuDeviceEntry(ctx context.Context, aWait bool) *OnuDeviceEntry {
mpagenko3af1f032020-06-10 08:53:41 +00001352 dh.lockDevice.RLock()
1353 pOnuDeviceEntry := dh.pOnuOmciDevice
1354 if aWait && pOnuDeviceEntry == nil {
1355 //keep the read sema short to allow for subsequent write
1356 dh.lockDevice.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001357 logger.Debugw(ctx, "Waiting for DeviceEntry to be set ...", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001358 // based on concurrent processing the deviceEntry setup may not yet be finished at his point
1359 // so it might be needed to wait here for that event with some timeout
1360 select {
1361 case <-time.After(60 * time.Second): //timer may be discussed ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Errorw(ctx, "No valid DeviceEntry set after maxTime", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001363 return nil
1364 case <-dh.deviceEntrySet:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001365 logger.Debugw(ctx, "devicEntry ready now - continue", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001366 // if written now, we can return the written value without sema
1367 return dh.pOnuOmciDevice
1368 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001369 }
mpagenko3af1f032020-06-10 08:53:41 +00001370 dh.lockDevice.RUnlock()
1371 return pOnuDeviceEntry
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001372}
1373
Himani Chawla6d2ae152020-09-02 13:11:20 +05301374//setOnuDeviceEntry sets the ONU device entry within the handler
1375func (dh *deviceHandler) setOnuDeviceEntry(
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001376 apDeviceEntry *OnuDeviceEntry, apOnuTp *onuUniTechProf, apOnuMetricsMgr *onuMetricsManager, apOnuAlarmMgr *onuAlarmManager, apSelfTestHdlr *selfTestControlBlock) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001377 dh.lockDevice.Lock()
1378 defer dh.lockDevice.Unlock()
mpagenkoaf801632020-07-03 10:00:42 +00001379 dh.pOnuOmciDevice = apDeviceEntry
1380 dh.pOnuTP = apOnuTp
Girish Gowdrae09a6202021-01-12 18:10:59 -08001381 dh.pOnuMetricsMgr = apOnuMetricsMgr
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301382 dh.pAlarmMgr = apOnuAlarmMgr
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001383 dh.pSelfTestHdlr = apSelfTestHdlr
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001384}
1385
Himani Chawla6d2ae152020-09-02 13:11:20 +05301386//addOnuDeviceEntry creates a new ONU device or returns the existing
1387func (dh *deviceHandler) addOnuDeviceEntry(ctx context.Context) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388 logger.Debugw(ctx, "adding-deviceEntry", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001389
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 deviceEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001391 if deviceEntry == nil {
1392 /* costum_me_map in python code seems always to be None,
1393 we omit that here first (declaration unclear) -> todo at Adapter specialization ...*/
1394 /* also no 'clock' argument - usage open ...*/
1395 /* and no alarm_db yet (oo.alarm_db) */
Holger Hildebrandt61b24d02020-11-16 13:36:40 +00001396 deviceEntry = newOnuDeviceEntry(ctx, dh)
mpagenko01e726e2020-10-23 09:45:29 +00001397 onuTechProfProc := newOnuUniTechProf(ctx, dh)
Girish Gowdrae09a6202021-01-12 18:10:59 -08001398 onuMetricsMgr := newonuMetricsManager(ctx, dh)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301399 onuAlarmManager := newAlarmManager(ctx, dh)
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001400 selfTestHdlr := newSelfTestMsgHandlerCb(ctx, dh)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001401 //error treatment possible //TODO!!!
Girish Gowdra6afb56a2021-04-27 17:47:57 -07001402 dh.setOnuDeviceEntry(deviceEntry, onuTechProfProc, onuMetricsMgr, onuAlarmManager, selfTestHdlr)
mpagenko3af1f032020-06-10 08:53:41 +00001403 // fire deviceEntry ready event to spread to possibly waiting processing
1404 dh.deviceEntrySet <- true
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405 logger.Debugw(ctx, "onuDeviceEntry-added", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001406 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407 logger.Debugw(ctx, "onuDeviceEntry-add: Device already exists", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001408 }
1409 // might be updated with some error handling !!!
1410 return nil
1411}
1412
dbainbri4d3a0dc2020-12-02 00:33:42 +00001413func (dh *deviceHandler) createInterface(ctx context.Context, onuind *oop.OnuIndication) error {
1414 logger.Debugw(ctx, "create_interface-started", log.Fields{"OnuId": onuind.GetOnuId(),
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001415 "OnuIntfId": onuind.GetIntfId(), "OnuSerialNumber": onuind.GetSerialNumber()})
1416
1417 dh.pOnuIndication = onuind // let's revise if storing the pointer is sufficient...
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001418
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001420 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001422 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1423 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001424 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 if err := dh.storePersistentData(ctx); err != nil {
1426 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001427 log.Fields{"device-id": dh.deviceID, "err": err})
1428 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "call DeviceStateUpdate upon create interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001430 "OperStatus": voltha.OperStatus_ACTIVATING, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001432 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVATING); err != nil {
1433 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001434 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001435 }
1436 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVATING",
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001438 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001439
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001440 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001441 if !pDevEntry.sOnuPersistentData.PersUniUnlockDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001442 pDevEntry.mutexPersOnuConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 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 +00001444 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001445 dh.stopReconciling(ctx)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001446 } else {
1447 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001448 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001449 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001450 // It does not look to me as if makes sense to work with the real core device here, (not the stored clone)?
1451 // in this code the GetDevice would just make a check if the DeviceID's Device still exists in core
1452 // 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 +00001453 // 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 +00001454 // so let's just try to keep it simple ...
1455 /*
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 device, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.device.Id, dh.device.Id)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00001457 if err != nil || device == nil {
1458 //TODO: needs to handle error scenarios
1459 logger.Errorw("Failed to fetch device device at creating If", log.Fields{"err": err})
1460 return errors.New("Voltha Device not found")
1461 }
1462 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001463
dbainbri4d3a0dc2020-12-02 00:33:42 +00001464 if err := pDevEntry.start(log.WithSpanFromContext(context.TODO(), ctx)); err != nil {
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001465 return err
mpagenko3af1f032020-06-10 08:53:41 +00001466 }
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001467
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001468 _ = dh.deviceReasonUpdate(ctx, drStartingOpenomci, !dh.isReconciling())
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001469
1470 /* this might be a good time for Omci Verify message? */
1471 verifyExec := make(chan bool)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001472 omciVerify := newOmciTestRequest(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko3af1f032020-06-10 08:53:41 +00001473 dh.device.Id, pDevEntry.PDevOmciCC,
mpagenko900ee4b2020-10-12 11:56:34 +00001474 true, true) //exclusive and allowFailure (anyway not yet checked)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 omciVerify.performOmciTest(log.WithSpanFromContext(context.TODO(), ctx), verifyExec)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001476
1477 /* give the handler some time here to wait for the OMCi verification result
1478 after Timeout start and try MibUpload FSM anyway
1479 (to prevent stopping on just not supported OMCI verification from ONU) */
1480 select {
Holger Hildebrandt366ef192021-05-05 11:07:44 +00001481 case <-time.After(pDevEntry.PDevOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 logger.Warn(ctx, "omci start-verification timed out (continue normal)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001483 case testresult := <-verifyExec:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Infow(ctx, "Omci start verification done", log.Fields{"result": testresult})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001485 }
1486
1487 /* In py code it looks earlier (on activate ..)
1488 # Code to Run OMCI Test Action
1489 kwargs_omci_test_action = {
1490 OmciTestRequest.DEFAULT_FREQUENCY_KEY:
1491 OmciTestRequest.DEFAULT_COLLECTION_FREQUENCY
1492 }
1493 serial_number = device.serial_number
1494 self._test_request = OmciTestRequest(self.core_proxy,
1495 self.omci_agent, self.device_id,
1496 AniG, serial_number,
1497 self.logical_device_id,
1498 exclusive=False,
1499 **kwargs_omci_test_action)
1500 ...
1501 # Start test requests after a brief pause
1502 if not self._test_request_started:
1503 self._test_request_started = True
1504 tststart = _STARTUP_RETRY_WAIT * (random.randint(1, 5))
1505 reactor.callLater(tststart, self._test_request.start_collector)
1506
1507 */
1508 /* which is then: in omci_test_request.py : */
1509 /*
1510 def start_collector(self, callback=None):
1511 """
1512 Start the collection loop for an adapter if the frequency > 0
1513
1514 :param callback: (callable) Function to call to collect PM data
1515 """
1516 self.logger.info("starting-pm-collection", device_name=self.name, default_freq=self.default_freq)
1517 if callback is None:
1518 callback = self.perform_test_omci
1519
1520 if self.lc is None:
1521 self.lc = LoopingCall(callback)
1522
1523 if self.default_freq > 0:
1524 self.lc.start(interval=self.default_freq / 10)
1525
1526 def perform_test_omci(self):
1527 """
1528 Perform the initial test request
1529 """
1530 ani_g_entities = self._device.configuration.ani_g_entities
1531 ani_g_entities_ids = list(ani_g_entities.keys()) if ani_g_entities \
1532 is not None else None
1533 self._entity_id = ani_g_entities_ids[0]
1534 self.logger.info('perform-test', entity_class=self._entity_class,
1535 entity_id=self._entity_id)
1536 try:
1537 frame = MEFrame(self._entity_class, self._entity_id, []).test()
1538 result = yield self._device.omci_cc.send(frame)
1539 if not result.fields['omci_message'].fields['success_code']:
1540 self.logger.info('Self-Test Submitted Successfully',
1541 code=result.fields[
1542 'omci_message'].fields['success_code'])
1543 else:
1544 raise TestFailure('Test Failure: {}'.format(
1545 result.fields['omci_message'].fields['success_code']))
1546 except TimeoutError as e:
1547 self.deferred.errback(failure.Failure(e))
1548
1549 except Exception as e:
1550 self.logger.exception('perform-test-Error', e=e,
1551 class_id=self._entity_class,
1552 entity_id=self._entity_id)
1553 self.deferred.errback(failure.Failure(e))
1554
1555 */
1556
1557 // PM related heartbeat??? !!!TODO....
1558 //self._heartbeat.enabled = True
1559
mpagenko1cc3cb42020-07-27 15:24:38 +00001560 /* Note: Even though FSM calls look 'synchronous' here, FSM is running in background with the effect that possible errors
1561 * within the MibUpload are not notified in the OnuIndication response, this might be acceptable here,
1562 * 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 +05301563 * otherwise some processing synchronization would be required - cmp. e.g TechProfile processing
mpagenko1cc3cb42020-07-27 15:24:38 +00001564 */
1565 //call MibUploadFSM - transition up to state ulStInSync
mpagenko3af1f032020-06-10 08:53:41 +00001566 pMibUlFsm := pDevEntry.pMibUploadFsm.pFsm
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001567 if pMibUlFsm != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00001568 if pMibUlFsm.Is(ulStDisabled) {
1569 if err := pMibUlFsm.Event(ulEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 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 +00001571 return fmt.Errorf("can't go to state starting: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301572 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 logger.Debugw(ctx, "MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Himani Chawla4d908332020-08-31 12:30:20 +05301574 //Determine ONU status and start/re-start MIB Synchronization tasks
1575 //Determine if this ONU has ever synchronized
Holger Hildebrandt0bd45f82021-01-11 13:29:37 +00001576 if pDevEntry.isNewOnu() {
Himani Chawla4d908332020-08-31 12:30:20 +05301577 if err := pMibUlFsm.Event(ulEvResetMib); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 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 +00001579 return fmt.Errorf("can't go to state resetting_mib: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001580 }
Himani Chawla4d908332020-08-31 12:30:20 +05301581 } else {
1582 if err := pMibUlFsm.Event(ulEvExamineMds); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 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 +00001584 return fmt.Errorf("can't go to examine_mds: %s", dh.deviceID)
Himani Chawla4d908332020-08-31 12:30:20 +05301585 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Debugw(ctx, "state of MibSyncFsm", log.Fields{"state": string(pMibUlFsm.Current())})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001587 }
Holger Hildebrandt9ac0d0f2020-05-13 11:22:02 +00001588 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001589 logger.Errorw(ctx, "wrong state of MibSyncFsm - want: disabled", log.Fields{"have": string(pMibUlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001590 "device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001591 return fmt.Errorf("wrong state of MibSyncFsm: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001592 }
1593 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Errorw(ctx, "MibSyncFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001595 return fmt.Errorf("can't execute MibSync: %s", dh.deviceID)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001596 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08001597
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001598 if !dh.getCollectorIsRunning() {
1599 // Start PM collector routine
1600 go dh.startCollector(ctx)
1601 }
Himani Chawla1472c682021-03-17 17:11:14 +05301602 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301603 go dh.startAlarmManager(ctx)
1604 }
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05301605
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001606 return nil
1607}
1608
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609func (dh *deviceHandler) updateInterface(ctx context.Context, onuind *oop.OnuIndication) error {
mpagenko3af1f032020-06-10 08:53:41 +00001610 //state checking to prevent unneeded processing (eg. on ONU 'unreachable' and 'down')
mpagenkofc4f56e2020-11-04 17:17:49 +00001611 // (but note that the deviceReason may also have changed to e.g. TechProf*Delete_Success in between)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001612 if dh.getDeviceReason() != drStoppingOpenomci {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Debugw(ctx, "updateInterface-started - stopping-device", log.Fields{"device-id": dh.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001614
mpagenko900ee4b2020-10-12 11:56:34 +00001615 //stop all running FSM processing - make use of the DH-state as mirrored in the deviceReason
1616 //here no conflict with aborted FSM's should arise as a complete OMCI initialization is assumed on ONU-Up
1617 //but that might change with some simple MDS check on ONU-Up treatment -> attention!!!
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001618 if err := dh.resetFsms(ctx, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Errorw(ctx, "error-updateInterface at FSM stop",
mpagenko900ee4b2020-10-12 11:56:34 +00001620 log.Fields{"device-id": dh.deviceID, "error": err})
1621 // abort: system behavior is just unstable ...
1622 return err
1623 }
mpagenkoa40e99a2020-11-17 13:50:39 +00001624 //all stored persistent data are not valid anymore (loosing knowledge about the connected ONU)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001625 _ = 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 +00001626
1627 //deviceEntry stop without omciCC reset here, regarding the OMCI_CC still valid for this ONU
1628 // - in contrary to disableDevice - compare with processUniDisableStateDoneEvent
1629 //stop the device entry which resets the attached omciCC
dbainbri4d3a0dc2020-12-02 00:33:42 +00001630 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko3af1f032020-06-10 08:53:41 +00001631 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001633 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
mpagenko3af1f032020-06-10 08:53:41 +00001634 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 _ = pDevEntry.stop(log.WithSpanFromContext(context.TODO(), ctx), false)
mpagenko3af1f032020-06-10 08:53:41 +00001636
1637 //TODO!!! remove existing traffic profiles
1638 /* from py code, if TP's exist, remove them - not yet implemented
1639 self._tp = dict()
1640 # Let TP download happen again
1641 for uni_id in self._tp_service_specific_task:
1642 self._tp_service_specific_task[uni_id].clear()
1643 for uni_id in self._tech_profile_download_done:
1644 self._tech_profile_download_done[uni_id].clear()
1645 */
1646
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 dh.disableUniPortStateUpdate(ctx)
mpagenko3af1f032020-06-10 08:53:41 +00001648
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001649 dh.setReadyForOmciConfig(false)
mpagenkofc4f56e2020-11-04 17:17:49 +00001650
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 if err := dh.deviceReasonUpdate(ctx, drStoppingOpenomci, true); err != nil {
mpagenko3af1f032020-06-10 08:53:41 +00001652 // abort: system behavior is just unstable ...
1653 return err
1654 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Debugw(ctx, "call DeviceStateUpdate upon update interface", log.Fields{"ConnectStatus": voltha.ConnectStatus_UNREACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001656 "OperStatus": voltha.OperStatus_DISCOVERED, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001657 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
mpagenko3af1f032020-06-10 08:53:41 +00001658 voltha.ConnectStatus_UNREACHABLE, voltha.OperStatus_DISCOVERED); err != nil {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00001659 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Errorw(ctx, "error-updating-device-state unreachable-discovered",
divyadesai4d299552020-08-18 07:13:49 +00001661 log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko3af1f032020-06-10 08:53:41 +00001662 // abort: system behavior is just unstable ...
1663 return err
1664 }
1665 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Debugw(ctx, "updateInterface - device already stopped", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00001667 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001668 return nil
1669}
1670
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001671func (dh *deviceHandler) resetFsms(ctx context.Context, includingMibSyncFsm bool) error {
mpagenko900ee4b2020-10-12 11:56:34 +00001672 //all possible FSM's are stopped or reset here to ensure their transition to 'disabled'
1673 //it is not sufficient to stop/reset the latest running FSM as done in previous versions
1674 // as after down/up procedures all FSM's might be active/ongoing (in theory)
1675 // and using the stop/reset event should never harm
1676
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
mpagenko900ee4b2020-10-12 11:56:34 +00001678 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001680 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
1681 }
Holger Hildebrandtc8ece362021-05-17 12:01:10 +00001682 if pDevEntry.PDevOmciCC != nil {
1683 pDevEntry.PDevOmciCC.CancelRequestMonitoring()
1684 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001685 if includingMibSyncFsm {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001686 pDevEntry.CancelProcessing(ctx)
mpagenko900ee4b2020-10-12 11:56:34 +00001687 }
1688 //MibDownload may run
1689 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1690 if pMibDlFsm != nil {
1691 _ = pMibDlFsm.Event(dlEvReset)
1692 }
1693 //port lock/unlock FSM's may be active
1694 if dh.pUnlockStateFsm != nil {
1695 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1696 }
1697 if dh.pLockStateFsm != nil {
1698 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
1699 }
1700 //techProfile related PonAniConfigFsm FSM may be active
1701 if dh.pOnuTP != nil {
1702 // should always be the case here
1703 // FSM stop maybe encapsulated as OnuTP method - perhaps later in context of module splitting
1704 if dh.pOnuTP.pAniConfigFsm != nil {
Girish Gowdra041dcb32020-11-16 16:54:30 -08001705 for uniTP := range dh.pOnuTP.pAniConfigFsm {
mpagenko73143992021-04-09 15:17:10 +00001706 dh.pOnuTP.pAniConfigFsm[uniTP].CancelProcessing(ctx)
Girish Gowdra041dcb32020-11-16 16:54:30 -08001707 }
mpagenko900ee4b2020-10-12 11:56:34 +00001708 }
1709 for _, uniPort := range dh.uniEntityMap {
mpagenko900ee4b2020-10-12 11:56:34 +00001710 // reset the possibly existing VlanConfigFsm
mpagenkof1fc3862021-02-16 10:09:52 +00001711 dh.lockVlanConfig.RLock()
mpagenko900ee4b2020-10-12 11:56:34 +00001712 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[uniPort.uniID]; exist {
1713 //VlanFilterFsm exists and was already started
mpagenko7d6bb022021-03-11 15:07:55 +00001714 dh.lockVlanConfig.RUnlock()
1715 //reset of all Fsm is always accompanied by global persistency data removal
1716 // no need to remove specific data
1717 pVlanFilterFsm.RequestClearPersistency(false)
1718 //ensure the FSM processing is stopped in case waiting for some response
mpagenko73143992021-04-09 15:17:10 +00001719 pVlanFilterFsm.CancelProcessing(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +00001720 } else {
1721 dh.lockVlanConfig.RUnlock()
mpagenko900ee4b2020-10-12 11:56:34 +00001722 }
1723 }
1724 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00001725 if dh.getCollectorIsRunning() {
1726 // Stop collector routine
1727 dh.stopCollector <- true
1728 }
Himani Chawla1472c682021-03-17 17:11:14 +05301729 if dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05301730 dh.stopAlarmManager <- true
1731 }
1732
mpagenko80622a52021-02-09 16:53:23 +00001733 //reset a possibly running upgrade FSM
1734 // specific here: If the FSM is in upgradeStWaitForCommit, it is left there for possibly later commit
1735 // this possibly also refers later to (not yet existing) upgradeStWaitForActivate (with ctl API changes)
1736 dh.lockUpgradeFsm.RLock()
1737 if dh.pOnuUpradeFsm != nil {
mpagenko59498c12021-03-18 14:15:15 +00001738 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
1739 if pUpgradeStatemachine != nil {
1740 if pUpgradeStatemachine.Is(upgradeStWaitEndDL) {
1741 dh.pOnuUpradeFsm.chReceiveExpectedResponse <- false //which aborts the FSM (activate was not yet sent)
1742 }
1743 _ = pUpgradeStatemachine.Event(upgradeEvReset) //anyway and for all other states
1744 }
1745 //else the FSM seems already to be in some released state
mpagenko80622a52021-02-09 16:53:23 +00001746 }
1747 dh.lockUpgradeFsm.RUnlock()
1748
mpagenko7d6bb022021-03-11 15:07:55 +00001749 logger.Infow(ctx, "resetFsms done", log.Fields{"device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001750 return nil
1751}
1752
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753func (dh *deviceHandler) processMibDatabaseSyncEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1754 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 +05301755
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001756 // store persistent data collected during MIB upload processing
1757 if err := dh.storePersistentData(ctx); err != nil {
1758 logger.Warnw(ctx, "store persistent data error - continue as there will be additional write attempts",
1759 log.Fields{"device-id": dh.deviceID, "err": err})
1760 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001761 _ = dh.deviceReasonUpdate(ctx, drDiscoveryMibsyncComplete, !dh.isReconciling())
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001762 dh.addAllUniPorts(ctx)
1763
mpagenkoa40e99a2020-11-17 13:50:39 +00001764 /* 200605: lock processing after initial MIBUpload removed now as the ONU should be in the lock state per default here */
1765 /* 201117: build_dt-berlin-pod-openonugo_1T8GEM_voltha_DT_openonugo_master_test runs into error TC
1766 * 'Test Disable ONUs and OLT Then Delete ONUs and OLT for DT' with Sercom ONU, which obviously needs
1767 * disable/enable toggling here to allow traffic
1768 * but moreover it might be useful for tracking the interface operState changes if this will be implemented,
1769 * like the py comment says:
1770 * # start by locking all the unis till mib sync and initial mib is downloaded
1771 * # this way we can capture the port down/up events when we are ready
1772 */
Himani Chawla26e555c2020-08-31 12:30:20 +05301773
mpagenkoa40e99a2020-11-17 13:50:39 +00001774 // Init Uni Ports to Admin locked state
1775 // *** should generate UniLockStateDone event *****
1776 if dh.pLockStateFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001777 dh.createUniLockFsm(ctx, true, UniLockStateDone)
mpagenkoa40e99a2020-11-17 13:50:39 +00001778 } else { //LockStateFSM already init
1779 dh.pLockStateFsm.setSuccessEvent(UniLockStateDone)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 dh.runUniLockFsm(ctx, true)
mpagenkoa40e99a2020-11-17 13:50:39 +00001781 }
1782}
1783
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784func (dh *deviceHandler) processUniLockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1785 logger.Infow(ctx, "UniLockStateDone event: Starting MIB download", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301786 /* Mib download procedure -
1787 ***** should run over 'downloaded' state and generate MibDownloadDone event *****
1788 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001790 if pDevEntry == nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001791 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001792 return
1793 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301794 pMibDlFsm := pDevEntry.pMibDownloadFsm.pFsm
1795 if pMibDlFsm != nil {
1796 if pMibDlFsm.Is(dlStDisabled) {
1797 if err := pMibDlFsm.Event(dlEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 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 +05301799 // maybe try a FSM reset and then again ... - TODO!!!
1800 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 logger.Debugw(ctx, "MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301802 // maybe use more specific states here for the specific download steps ...
1803 if err := pMibDlFsm.Event(dlEvCreateGal); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804 logger.Errorw(ctx, "MibDownloadFsm: Can't start CreateGal", log.Fields{"device-id": dh.deviceID, "err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301805 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001806 logger.Debugw(ctx, "state of MibDownloadFsm", log.Fields{"state": string(pMibDlFsm.Current())})
Himani Chawla26e555c2020-08-31 12:30:20 +05301807 //Begin MIB data download (running autonomously)
1808 }
1809 }
1810 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001811 logger.Errorw(ctx, "wrong state of MibDownloadFsm - want: disabled", log.Fields{"have": string(pMibDlFsm.Current()),
mpagenko01e726e2020-10-23 09:45:29 +00001812 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301813 // maybe try a FSM reset and then again ... - TODO!!!
1814 }
1815 /***** Mib download started */
1816 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001817 logger.Errorw(ctx, "MibDownloadFsm invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301818 }
1819}
1820
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821func (dh *deviceHandler) processMibDownloadDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1822 logger.Debugw(ctx, "MibDownloadDone event received, unlocking the ONU interfaces", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301823 //initiate DevStateUpdate
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001824 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 logger.Debugw(ctx, "call DeviceStateUpdate upon mib-download done", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00001826 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00001827 //we allow a possible OnuSw image commit only in the normal startup, not at reconciling
1828 // in case of adapter restart connected to an ONU upgrade I would not rely on the image quality
1829 // maybe some 'forced' commitment can be done in this situation from system management (or upgrade restarted)
1830 dh.checkOnOnuImageCommit(ctx)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001831 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05301832 voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE); err != nil {
1833 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05301835 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 logger.Debugw(ctx, "dev state updated to 'Oper.Active'", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301837 }
1838 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 logger.Debugw(ctx, "reconciling - don't notify core about DeviceStateUpdate to ACTIVE",
Himani Chawla26e555c2020-08-31 12:30:20 +05301840 log.Fields{"device-id": dh.deviceID})
1841 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001842 _ = dh.deviceReasonUpdate(ctx, drInitialMibDownloaded, !dh.isReconciling())
Girish Gowdrae0140f02021-02-02 16:55:09 -08001843
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07001844 if !dh.getCollectorIsRunning() {
1845 // Start PM collector routine
1846 go dh.startCollector(ctx)
1847 }
1848 if !dh.getAlarmManagerIsRunning(ctx) {
1849 go dh.startAlarmManager(ctx)
1850 }
1851
Girish Gowdrae0140f02021-02-02 16:55:09 -08001852 // Initialize classical L2 PM Interval Counters
1853 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventInit); err != nil {
1854 // There is no way we should be landing here, but if we do then
1855 // there is nothing much we can do about this other than log error
1856 logger.Errorw(ctx, "error starting l2 pm fsm", log.Fields{"device-id": dh.device.Id, "err": err})
1857 }
1858
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001859 dh.setReadyForOmciConfig(true)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001860
1861 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
1862 if pDevEntry == nil {
1863 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
1864 return
1865 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001866 pDevEntry.mutexPersOnuConfig.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001867 if dh.isReconciling() && pDevEntry.sOnuPersistentData.PersUniDisableDone {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001868 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001869 logger.Debugw(ctx, "reconciling - uni-ports were disabled by admin before adapter restart - keep the ports locked",
1870 log.Fields{"device-id": dh.deviceID})
1871 go dh.reconcileDeviceTechProf(ctx)
1872 // reconcilement will be continued after ani config is done
1873 } else {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001874 pDevEntry.mutexPersOnuConfig.RUnlock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001875 // *** should generate UniUnlockStateDone event *****
1876 if dh.pUnlockStateFsm == nil {
1877 dh.createUniLockFsm(ctx, false, UniUnlockStateDone)
1878 } else { //UnlockStateFSM already init
1879 dh.pUnlockStateFsm.setSuccessEvent(UniUnlockStateDone)
1880 dh.runUniLockFsm(ctx, false)
1881 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301882 }
1883}
1884
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885func (dh *deviceHandler) processUniUnlockStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1886 dh.enableUniPortStateUpdate(ctx) //cmp python yield self.enable_ports()
Himani Chawla26e555c2020-08-31 12:30:20 +05301887
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001888 if !dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001889 logger.Infow(ctx, "UniUnlockStateDone event: Sending OnuUp event", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05301890 raisedTs := time.Now().UnixNano()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 go dh.sendOnuOperStateEvent(ctx, voltha.OperStatus_ACTIVE, dh.deviceID, raisedTs) //cmp python onu_active_event
1892 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001893 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001894 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001895 return
1896 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001897 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001898 pDevEntry.sOnuPersistentData.PersUniUnlockDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001899 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001900 if err := dh.storePersistentData(ctx); err != nil {
1901 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001902 log.Fields{"device-id": dh.deviceID, "err": err})
1903 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301904 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 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 +05301906 log.Fields{"device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 go dh.reconcileDeviceTechProf(ctx)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001908 // reconcilement will be continued after ani config is done
Himani Chawla26e555c2020-08-31 12:30:20 +05301909 }
1910}
1911
dbainbri4d3a0dc2020-12-02 00:33:42 +00001912func (dh *deviceHandler) processUniDisableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1913 logger.Debugw(ctx, "DeviceStateUpdate upon disable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001914 "OperStatus": voltha.OperStatus_UNKNOWN, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001915 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx),
mpagenko900ee4b2020-10-12 11:56:34 +00001916 dh.deviceID, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_UNKNOWN); err != nil {
1917 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001919 }
1920
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 logger.Debugw(ctx, "DeviceReasonUpdate upon disable", log.Fields{"reason": deviceReasonMap[drOmciAdminLock], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001922 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 _ = dh.deviceReasonUpdate(ctx, drOmciAdminLock, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001924
1925 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001926 dh.disableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001927
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001929 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001931 return
1932 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001933 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001934 pDevEntry.sOnuPersistentData.PersUniDisableDone = true
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001935 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 if err := dh.storePersistentData(ctx); err != nil {
1937 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001938 log.Fields{"device-id": dh.deviceID, "err": err})
1939 }
mpagenko900ee4b2020-10-12 11:56:34 +00001940}
1941
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942func (dh *deviceHandler) processUniEnableStateDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
1943 logger.Debugw(ctx, "DeviceStateUpdate upon re-enable", log.Fields{"ConnectStatus": voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001944 "OperStatus": voltha.OperStatus_ACTIVE, "device-id": dh.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 if err := dh.coreProxy.DeviceStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.ConnectStatus_REACHABLE,
mpagenko900ee4b2020-10-12 11:56:34 +00001946 voltha.OperStatus_ACTIVE); err != nil {
1947 //TODO with VOL-3045/VOL-3046: return the error and stop further processing
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 logger.Errorw(ctx, "error-updating-device-state", log.Fields{"device-id": dh.deviceID, "error": err})
mpagenko900ee4b2020-10-12 11:56:34 +00001949 }
1950
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Debugw(ctx, "DeviceReasonUpdate upon re-enable", log.Fields{
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001952 "reason": deviceReasonMap[drOnuReenabled], "device-id": dh.deviceID})
mpagenko900ee4b2020-10-12 11:56:34 +00001953 // DeviceReason to update acc.to modified py code as per beginning of Sept 2020
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 _ = dh.deviceReasonUpdate(ctx, drOnuReenabled, true)
mpagenko900ee4b2020-10-12 11:56:34 +00001955
1956 //transfer the modified logical uni port state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 dh.enableUniPortStateUpdate(ctx)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001958
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001960 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001962 return
1963 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001964 pDevEntry.mutexPersOnuConfig.Lock()
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001965 pDevEntry.sOnuPersistentData.PersUniDisableDone = false
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001966 pDevEntry.mutexPersOnuConfig.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 if err := dh.storePersistentData(ctx); err != nil {
1968 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00001969 log.Fields{"device-id": dh.deviceID, "err": err})
1970 }
mpagenko900ee4b2020-10-12 11:56:34 +00001971}
1972
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973func (dh *deviceHandler) processOmciAniConfigDoneEvent(ctx context.Context, devEvent OnuDeviceEvent) {
mpagenkofc4f56e2020-11-04 17:17:49 +00001974 if devEvent == OmciAniConfigDone {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "OmciAniConfigDone event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001976 // attention: the device reason update is done based on ONU-UNI-Port related activity
1977 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001978 if dh.getDeviceReason() != drTechProfileConfigDownloadSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001979 // 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 +00001980 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDownloadSuccess, !dh.isReconciling())
Himani Chawla26e555c2020-08-31 12:30:20 +05301981 }
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00001982 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 go dh.reconcileDeviceFlowConfig(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001984 }
1985 } else { // should be the OmciAniResourceRemoved block
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Debugw(ctx, "OmciAniResourceRemoved event received", log.Fields{"device-id": dh.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001987 // attention: the device reason update is done based on ONU-UNI-Port related activity
1988 // - which may cause some inconsistency
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001989 if dh.getDeviceReason() != drTechProfileConfigDeleteSuccess {
mpagenkofc4f56e2020-11-04 17:17:49 +00001990 // 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 +00001991 _ = dh.deviceReasonUpdate(ctx, drTechProfileConfigDeleteSuccess, true)
mpagenkofc4f56e2020-11-04 17:17:49 +00001992 }
Holger Hildebrandt47555e72020-09-21 11:07:24 +00001993 }
Himani Chawla26e555c2020-08-31 12:30:20 +05301994}
1995
dbainbri4d3a0dc2020-12-02 00:33:42 +00001996func (dh *deviceHandler) processOmciVlanFilterDoneEvent(ctx context.Context, aDevEvent OnuDeviceEvent) {
1997 logger.Debugw(ctx, "OmciVlanFilterDone event received",
mpagenkofc4f56e2020-11-04 17:17:49 +00001998 log.Fields{"device-id": dh.deviceID, "event": aDevEvent})
Himani Chawla26e555c2020-08-31 12:30:20 +05301999 // attention: the device reason update is done based on ONU-UNI-Port related activity
2000 // - which may cause some inconsistency
Himani Chawla26e555c2020-08-31 12:30:20 +05302001
mpagenkof1fc3862021-02-16 10:09:52 +00002002 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterAddDoneNoKvStore {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002003 if dh.getDeviceReason() != drOmciFlowsPushed {
mpagenkofc4f56e2020-11-04 17:17:49 +00002004 // which may be the case from some previous actvity on another UNI Port of the ONU
2005 // or even some previous flow add activity on the same port
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002006 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsPushed, !dh.isReconciling())
2007 if dh.isReconciling() {
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00002008 go dh.reconcileEnd(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00002009 }
2010 }
2011 } else {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002012 if dh.getDeviceReason() != drOmciFlowsDeleted {
mpagenkofc4f56e2020-11-04 17:17:49 +00002013 //not relevant for reconcile
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 _ = dh.deviceReasonUpdate(ctx, drOmciFlowsDeleted, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002015 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302016 }
mpagenkof1fc3862021-02-16 10:09:52 +00002017
2018 if aDevEvent == OmciVlanFilterAddDone || aDevEvent == OmciVlanFilterRemDone {
2019 //events that request KvStore write
2020 if err := dh.storePersistentData(ctx); err != nil {
2021 logger.Warnw(ctx, "store persistent data error - continue for now as there will be additional write attempts",
2022 log.Fields{"device-id": dh.deviceID, "err": err})
2023 }
2024 } else {
2025 logger.Debugw(ctx, "OmciVlanFilter*Done* - write to KvStore not requested",
2026 log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002027 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302028}
2029
Himani Chawla6d2ae152020-09-02 13:11:20 +05302030//deviceProcStatusUpdate evaluates possible processing events and initiates according next activities
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031func (dh *deviceHandler) deviceProcStatusUpdate(ctx context.Context, devEvent OnuDeviceEvent) {
Himani Chawla4d908332020-08-31 12:30:20 +05302032 switch devEvent {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002033 case MibDatabaseSync:
2034 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002035 dh.processMibDatabaseSyncEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002036 }
mpagenkoa40e99a2020-11-17 13:50:39 +00002037 case UniLockStateDone:
2038 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 dh.processUniLockStateDoneEvent(ctx, devEvent)
mpagenkoa40e99a2020-11-17 13:50:39 +00002040 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002041 case MibDownloadDone:
2042 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043 dh.processMibDownloadDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002044 }
2045 case UniUnlockStateDone:
2046 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 dh.processUniUnlockStateDoneEvent(ctx, devEvent)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002048 }
mpagenko900ee4b2020-10-12 11:56:34 +00002049 case UniEnableStateDone:
2050 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 dh.processUniEnableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002052 }
2053 case UniDisableStateDone:
2054 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002055 dh.processUniDisableStateDoneEvent(ctx, devEvent)
mpagenko900ee4b2020-10-12 11:56:34 +00002056 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002057 case OmciAniConfigDone, OmciAniResourceRemoved:
mpagenko3dbcdd22020-07-22 07:38:45 +00002058 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 dh.processOmciAniConfigDoneEvent(ctx, devEvent)
mpagenko3dbcdd22020-07-22 07:38:45 +00002060 }
mpagenkof1fc3862021-02-16 10:09:52 +00002061 case OmciVlanFilterAddDone, OmciVlanFilterAddDoneNoKvStore, OmciVlanFilterRemDone, OmciVlanFilterRemDoneNoKvStore:
mpagenkodff5dda2020-08-28 11:52:01 +00002062 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 dh.processOmciVlanFilterDoneEvent(ctx, devEvent)
mpagenkodff5dda2020-08-28 11:52:01 +00002064 }
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002065 default:
2066 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Debugw(ctx, "unhandled-device-event", log.Fields{"device-id": dh.deviceID, "event": devEvent})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002068 }
2069 } //switch
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002070}
2071
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072func (dh *deviceHandler) addUniPort(ctx context.Context, aUniInstNo uint16, aUniID uint8, aPortType uniPortType) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002073 // parameters are IntfId, OnuId, uniId
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074 uniNo := mkUniPortNum(ctx, dh.pOnuIndication.GetIntfId(), dh.pOnuIndication.GetOnuId(),
Himani Chawla4d908332020-08-31 12:30:20 +05302075 uint32(aUniID))
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002076 if _, present := dh.uniEntityMap[uniNo]; present {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077 logger.Warnw(ctx, "onuUniPort-add: Port already exists", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002078 } else {
Himani Chawla4d908332020-08-31 12:30:20 +05302079 //with arguments aUniID, a_portNo, aPortType
dbainbri4d3a0dc2020-12-02 00:33:42 +00002080 pUniPort := newOnuUniPort(ctx, aUniID, uniNo, aUniInstNo, aPortType)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002081 if pUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Warnw(ctx, "onuUniPort-add: Could not create Port", log.Fields{"for InstanceId": aUniInstNo})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002083 } else {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002084 //store UniPort with the System-PortNumber key
2085 dh.uniEntityMap[uniNo] = pUniPort
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002086 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002087 // create announce the UniPort to the core as VOLTHA Port object
dbainbri4d3a0dc2020-12-02 00:33:42 +00002088 if err := pUniPort.createVolthaPort(ctx, dh); err == nil {
2089 logger.Infow(ctx, "onuUniPort-added", log.Fields{"for PortNo": uniNo})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002090 } //error logging already within UniPort method
2091 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002092 logger.Debugw(ctx, "reconciling - onuUniPort already added", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002093 }
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00002094 }
2095 }
2096}
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002097
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002098func (dh *deviceHandler) addAllUniPorts(ctx context.Context) {
2099 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2100 if pDevEntry == nil {
2101 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
2102 return
2103 }
2104 i := uint8(0) //UNI Port limit: see MaxUnisPerOnu (by now 16) (OMCI supports max 255 p.b.)
2105 if pptpInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2106 ctx, me.PhysicalPathTerminationPointEthernetUniClassID); len(pptpInstKeys) > 0 {
2107 for _, mgmtEntityID := range pptpInstKeys {
2108 logger.Debugw(ctx, "Add PPTPEthUni port for MIB-stored instance:", log.Fields{
2109 "device-id": dh.deviceID, "PPTPEthUni EntityID": mgmtEntityID})
2110 dh.addUniPort(ctx, mgmtEntityID, i, uniPPTP)
2111 i++
2112 }
2113 } else {
2114 logger.Debugw(ctx, "No PPTP instances found", log.Fields{"device-id": dh.deviceID})
2115 }
2116 if veipInstKeys := pDevEntry.pOnuDB.getSortedInstKeys(
2117 ctx, me.VirtualEthernetInterfacePointClassID); len(veipInstKeys) > 0 {
2118 for _, mgmtEntityID := range veipInstKeys {
2119 logger.Debugw(ctx, "Add VEIP for MIB-stored instance:", log.Fields{
2120 "device-id": dh.deviceID, "VEIP EntityID": mgmtEntityID})
2121 dh.addUniPort(ctx, mgmtEntityID, i, uniVEIP)
2122 i++
2123 }
2124 } else {
2125 logger.Debugw(ctx, "No VEIP instances found", log.Fields{"device-id": dh.deviceID})
2126 }
2127 if i == 0 {
2128 logger.Warnw(ctx, "No UniG instances found", log.Fields{"device-id": dh.deviceID})
2129 }
2130}
2131
mpagenko3af1f032020-06-10 08:53:41 +00002132// enableUniPortStateUpdate enables UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133func (dh *deviceHandler) enableUniPortStateUpdate(ctx context.Context) {
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002134 // py code was updated 2003xx to activate the real ONU UNI ports per OMCI (VEIP or PPTP)
Himani Chawla4d908332020-08-31 12:30:20 +05302135 // but towards core only the first port active state is signaled
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002136 // with following remark:
2137 // # TODO: for now only support the first UNI given no requirement for multiple uni yet. Also needed to reduce flow
2138 // # load on the core
2139
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002140 // 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 +00002141
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002142 for uniNo, uniPort := range dh.uniEntityMap {
mpagenko3af1f032020-06-10 08:53:41 +00002143 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302144 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002145 logger.Infow(ctx, "onuUniPort-forced-OperState-ACTIVE", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302146 uniPort.setOperState(vc.OperStatus_ACTIVE)
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002147 if !dh.isReconciling() {
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002148 //maybe also use getter functions on uniPort - perhaps later ...
dbainbri4d3a0dc2020-12-02 00:33:42 +00002149 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 +00002150 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002151 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtf41a1602020-08-19 09:52:50 +00002152 }
mpagenko3af1f032020-06-10 08:53:41 +00002153 }
2154 }
2155}
2156
2157// Disable UniPortState and update core port state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00002158func (dh *deviceHandler) disableUniPortStateUpdate(ctx context.Context) {
mpagenko3af1f032020-06-10 08:53:41 +00002159 // compare enableUniPortStateUpdate() above
2160 // -> use current restriction to operate only on first UNI port as inherited from actual Py code
2161 for uniNo, uniPort := range dh.uniEntityMap {
2162 // only if this port is validated for operState transfer
Himani Chawla6d2ae152020-09-02 13:11:20 +05302163 if (1<<uniPort.uniID)&activeUniPortStateUpdateMask == (1 << uniPort.uniID) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00002164 logger.Infow(ctx, "onuUniPort-forced-OperState-UNKNOWN", log.Fields{"for PortNo": uniNo, "device-id": dh.deviceID})
Himani Chawla6d2ae152020-09-02 13:11:20 +05302165 uniPort.setOperState(vc.OperStatus_UNKNOWN)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002166 if !dh.isReconciling() {
2167 //maybe also use getter functions on uniPort - perhaps later ...
2168 go dh.coreProxy.PortStateUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, voltha.Port_ETHERNET_UNI, uniPort.portNo, uniPort.operState)
2169 } else {
2170 logger.Debugw(ctx, "reconciling - don't notify core about PortStateUpdate", log.Fields{"device-id": dh.deviceID})
2171 }
2172
Holger Hildebrandtbe674422020-05-05 13:05:30 +00002173 }
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002174 }
2175}
2176
2177// ONU_Active/Inactive announcement on system KAFKA bus
2178// tried to re-use procedure of oltUpDownIndication from openolt_eventmgr.go with used values from Py code
dbainbri4d3a0dc2020-12-02 00:33:42 +00002179func (dh *deviceHandler) sendOnuOperStateEvent(ctx context.Context, aOperState vc.OperStatus_Types, aDeviceID string, raisedTs int64) {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002180 var de voltha.DeviceEvent
2181 eventContext := make(map[string]string)
2182 //Populating event context
2183 // assume giving ParentId in GetDevice twice really gives the ParentDevice (there is no GetParentDevice()...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184 parentDevice, err := dh.coreProxy.GetDevice(log.WithSpanFromContext(context.TODO(), ctx), dh.parentID, dh.parentID)
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002185 if err != nil || parentDevice == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Errorw(ctx, "Failed to fetch parent device for OnuEvent",
Himani Chawla4d908332020-08-31 12:30:20 +05302187 log.Fields{"parentID": dh.parentID, "err": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002188 }
2189 oltSerialNumber := parentDevice.SerialNumber
2190
2191 eventContext["pon-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.IntfId), 10)
2192 eventContext["onu-id"] = strconv.FormatUint(uint64(dh.pOnuIndication.OnuId), 10)
2193 eventContext["serial-number"] = dh.device.SerialNumber
ssiddiqui1221d1a2021-02-15 11:12:51 +05302194 eventContext["olt-serial-number"] = oltSerialNumber
2195 eventContext["device-id"] = aDeviceID
2196 eventContext["registration-id"] = aDeviceID //py: string(device_id)??
dbainbri4d3a0dc2020-12-02 00:33:42 +00002197 logger.Debugw(ctx, "prepare ONU_ACTIVATED event",
mpagenko01e726e2020-10-23 09:45:29 +00002198 log.Fields{"device-id": aDeviceID, "EventContext": eventContext})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002199
2200 /* Populating device event body */
2201 de.Context = eventContext
Himani Chawla4d908332020-08-31 12:30:20 +05302202 de.ResourceId = aDeviceID
2203 if aOperState == voltha.OperStatus_ACTIVE {
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002204 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "RAISE_EVENT")
2205 de.Description = fmt.Sprintf("%s Event - %s - %s",
2206 cEventObjectType, cOnuActivatedEvent, "Raised")
2207 } else {
2208 de.DeviceEventName = fmt.Sprintf("%s_%s", cOnuActivatedEvent, "CLEAR_EVENT")
2209 de.Description = fmt.Sprintf("%s Event - %s - %s",
2210 cEventObjectType, cOnuActivatedEvent, "Cleared")
2211 }
2212 /* Send event to KAFKA */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 if err := dh.EventProxy.SendDeviceEvent(ctx, &de, equipment, pon, raisedTs); err != nil {
2214 logger.Warnw(ctx, "could not send ONU_ACTIVATED event",
Himani Chawla4d908332020-08-31 12:30:20 +05302215 log.Fields{"device-id": aDeviceID, "error": err})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002216 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Debugw(ctx, "ctx, ONU_ACTIVATED event sent to KAFKA",
Himani Chawla4d908332020-08-31 12:30:20 +05302218 log.Fields{"device-id": aDeviceID, "with-EventName": de.DeviceEventName})
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002219}
2220
Himani Chawla4d908332020-08-31 12:30:20 +05302221// createUniLockFsm initializes and runs the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222func (dh *deviceHandler) createUniLockFsm(ctx context.Context, aAdminState bool, devEvent OnuDeviceEvent) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002223 chLSFsm := make(chan Message, 2048)
2224 var sFsmName string
Himani Chawla4d908332020-08-31 12:30:20 +05302225 if aAdminState {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Debugw(ctx, "createLockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002227 sFsmName = "LockStateFSM"
2228 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Debugw(ctx, "createUnlockStateFSM", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002230 sFsmName = "UnLockStateFSM"
2231 }
mpagenko3af1f032020-06-10 08:53:41 +00002232
dbainbri4d3a0dc2020-12-02 00:33:42 +00002233 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenko3af1f032020-06-10 08:53:41 +00002234 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
mpagenko3af1f032020-06-10 08:53:41 +00002236 return
2237 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 pLSFsm := newLockStateFsm(ctx, pDevEntry.PDevOmciCC, aAdminState, devEvent,
Holger Hildebrandt8165eda2020-09-24 09:39:24 +00002239 sFsmName, dh, chLSFsm)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002240 if pLSFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05302241 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002242 dh.pLockStateFsm = pLSFsm
2243 } else {
2244 dh.pUnlockStateFsm = pLSFsm
2245 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002246 dh.runUniLockFsm(ctx, aAdminState)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002247 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002248 logger.Errorw(ctx, "LockStateFSM could not be created - abort!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002249 }
2250}
2251
2252// runUniLockFsm starts the UniLock FSM to transfer the OMCI related commands for port lock/unlock
dbainbri4d3a0dc2020-12-02 00:33:42 +00002253func (dh *deviceHandler) runUniLockFsm(ctx context.Context, aAdminState bool) {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002254 /* Uni Port lock/unlock procedure -
2255 ***** should run via 'adminDone' state and generate the argument requested event *****
2256 */
2257 var pLSStatemachine *fsm.FSM
Himani Chawla4d908332020-08-31 12:30:20 +05302258 if aAdminState {
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002259 pLSStatemachine = dh.pLockStateFsm.pAdaptFsm.pFsm
2260 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2261 if (dh.pUnlockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002262 (dh.pUnlockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302263 _ = dh.pUnlockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002264 }
2265 } else {
2266 pLSStatemachine = dh.pUnlockStateFsm.pAdaptFsm.pFsm
2267 //make sure the opposite FSM is not running and if so, terminate it as not relevant anymore
2268 if (dh.pLockStateFsm != nil) &&
mpagenko1cc3cb42020-07-27 15:24:38 +00002269 (dh.pLockStateFsm.pAdaptFsm.pFsm.Current() != uniStDisabled) {
Himani Chawla4d908332020-08-31 12:30:20 +05302270 _ = dh.pLockStateFsm.pAdaptFsm.pFsm.Event(uniEvReset)
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002271 }
2272 }
2273 if pLSStatemachine != nil {
mpagenko1cc3cb42020-07-27 15:24:38 +00002274 if pLSStatemachine.Is(uniStDisabled) {
2275 if err := pLSStatemachine.Event(uniEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002276 logger.Warnw(ctx, "LockStateFSM: can't start", log.Fields{"err": err})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002277 // maybe try a FSM reset and then again ... - TODO!!!
2278 } else {
2279 /***** LockStateFSM started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 logger.Debugw(ctx, "LockStateFSM started", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002281 "state": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002282 }
2283 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002284 logger.Warnw(ctx, "wrong state of LockStateFSM - want: disabled", log.Fields{
divyadesai4d299552020-08-18 07:13:49 +00002285 "have": pLSStatemachine.Current(), "device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002286 // maybe try a FSM reset and then again ... - TODO!!!
2287 }
2288 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 logger.Errorw(ctx, "LockStateFSM StateMachine invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandtccd390c2020-05-29 13:49:04 +00002290 // maybe try a FSM reset and then again ... - TODO!!!
2291 }
2292}
2293
mpagenko80622a52021-02-09 16:53:23 +00002294// createOnuUpgradeFsm initializes and runs the Onu Software upgrade FSM
mpagenko15ff4a52021-03-02 10:09:20 +00002295func (dh *deviceHandler) createOnuUpgradeFsm(ctx context.Context, apDevEntry *OnuDeviceEntry, aDevEvent OnuDeviceEvent) error {
mpagenko80622a52021-02-09 16:53:23 +00002296 //in here lockUpgradeFsm is already locked
2297 chUpgradeFsm := make(chan Message, 2048)
2298 var sFsmName = "OnuSwUpgradeFSM"
2299 logger.Debugw(ctx, "create OnuSwUpgradeFSM", log.Fields{"device-id": dh.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +00002300 if apDevEntry.PDevOmciCC == nil {
2301 logger.Errorw(ctx, "no valid OnuDevice or omciCC - abort", log.Fields{"device-id": dh.deviceID})
2302 return fmt.Errorf(fmt.Sprintf("no valid omciCC - abort for device-id: %s", dh.device.Id))
mpagenko80622a52021-02-09 16:53:23 +00002303 }
mpagenko15ff4a52021-03-02 10:09:20 +00002304 dh.pOnuUpradeFsm = NewOnuUpgradeFsm(ctx, dh, apDevEntry, apDevEntry.pOnuDB, aDevEvent,
mpagenko80622a52021-02-09 16:53:23 +00002305 sFsmName, chUpgradeFsm)
2306 if dh.pOnuUpradeFsm != nil {
2307 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2308 if pUpgradeStatemachine != nil {
2309 if pUpgradeStatemachine.Is(upgradeStDisabled) {
2310 if err := pUpgradeStatemachine.Event(upgradeEvStart); err != nil {
2311 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't start", log.Fields{"err": err})
2312 // maybe try a FSM reset and then again ... - TODO!!!
2313 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s", dh.device.Id))
2314 }
2315 /***** LockStateFSM started */
2316 logger.Debugw(ctx, "OnuSwUpgradeFSM started", log.Fields{
2317 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2318 } else {
2319 logger.Errorw(ctx, "wrong state of OnuSwUpgradeFSM to start - want: disabled", log.Fields{
2320 "have": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2321 // maybe try a FSM reset and then again ... - TODO!!!
2322 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be started for device-id: %s, wrong internal state", dh.device.Id))
2323 }
2324 } else {
2325 logger.Errorw(ctx, "OnuSwUpgradeFSM internal FSM invalid - cannot be executed!!", log.Fields{"device-id": dh.deviceID})
2326 // maybe try a FSM reset and then again ... - TODO!!!
2327 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM internal FSM could not be created for device-id: %s", dh.device.Id))
2328 }
2329 } else {
2330 logger.Errorw(ctx, "OnuSwUpgradeFSM could not be created - abort", log.Fields{"device-id": dh.deviceID})
2331 return fmt.Errorf(fmt.Sprintf("OnuSwUpgradeFSM could not be created - abort for device-id: %s", dh.device.Id))
2332 }
2333 return nil
2334}
2335
2336// removeOnuUpgradeFsm clears the Onu Software upgrade FSM
2337func (dh *deviceHandler) removeOnuUpgradeFsm(ctx context.Context) {
2338 logger.Debugw(ctx, "remove OnuSwUpgradeFSM StateMachine", log.Fields{
2339 "device-id": dh.deviceID})
2340 dh.lockUpgradeFsm.Lock()
2341 defer dh.lockUpgradeFsm.Unlock()
2342 dh.pOnuUpradeFsm = nil //resource clearing is left to garbage collector
2343}
2344
mpagenko15ff4a52021-03-02 10:09:20 +00002345// checkOnOnuImageCommit verifies if the ONU is in some upgrade state that allows for image commit and if tries to commit
2346func (dh *deviceHandler) checkOnOnuImageCommit(ctx context.Context) {
2347 pDevEntry := dh.getOnuDeviceEntry(ctx, false)
2348 if pDevEntry == nil {
2349 logger.Errorw(ctx, "No valid OnuDevice -aborting checkOnOnuImageCommit", log.Fields{"device-id": dh.deviceID})
2350 return
2351 }
2352
2353 dh.lockUpgradeFsm.RLock()
2354 defer dh.lockUpgradeFsm.RUnlock()
2355 if dh.pOnuUpradeFsm != nil {
2356 pUpgradeStatemachine := dh.pOnuUpradeFsm.pAdaptFsm.pFsm
2357 if pUpgradeStatemachine != nil {
2358 // commit is only processed in case out upgrade FSM indicates the according state (for automatic commit)
2359 // (some manual forced commit could do without)
2360 if pUpgradeStatemachine.Is(upgradeStWaitForCommit) {
mpagenko59498c12021-03-18 14:15:15 +00002361 if pDevEntry.IsImageToBeCommitted(ctx, dh.pOnuUpradeFsm.inactiveImageMeID) {
mpagenko15ff4a52021-03-02 10:09:20 +00002362 if err := pUpgradeStatemachine.Event(upgradeEvCommitSw); err != nil {
2363 logger.Errorw(ctx, "OnuSwUpgradeFSM: can't call commit event", log.Fields{"err": err})
2364 return
2365 }
2366 logger.Debugw(ctx, "OnuSwUpgradeFSM commit image requested", log.Fields{
2367 "state": pUpgradeStatemachine.Current(), "device-id": dh.deviceID})
2368 } else {
2369 logger.Errorw(ctx, "OnuSwUpgradeFSM waiting to commit, but nothing to commit on ONU - abort upgrade",
2370 log.Fields{"device-id": dh.deviceID})
2371 _ = pUpgradeStatemachine.Event(upgradeEvAbort)
2372 return
2373 }
2374 }
2375 }
2376 } else {
2377 logger.Debugw(ctx, "no ONU image to be committed", log.Fields{"device-id": dh.deviceID})
2378 }
2379}
2380
Himani Chawla6d2ae152020-09-02 13:11:20 +05302381//setBackend provides a DB backend for the specified path on the existing KV client
dbainbri4d3a0dc2020-12-02 00:33:42 +00002382func (dh *deviceHandler) setBackend(ctx context.Context, aBasePathKvStore string) *db.Backend {
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002383
2384 logger.Debugw(ctx, "SetKVStoreBackend", log.Fields{"IpTarget": dh.pOpenOnuAc.KVStoreAddress,
divyadesai4d299552020-08-18 07:13:49 +00002385 "BasePathKvStore": aBasePathKvStore, "device-id": dh.deviceID})
mpagenkoaf801632020-07-03 10:00:42 +00002386 kvbackend := &db.Backend{
2387 Client: dh.pOpenOnuAc.kvClient,
2388 StoreType: dh.pOpenOnuAc.KVStoreType,
2389 /* address config update acc. to [VOL-2736] */
Matteo Scandolo127c59d2021-01-28 11:31:18 -08002390 Address: dh.pOpenOnuAc.KVStoreAddress,
mpagenkoaf801632020-07-03 10:00:42 +00002391 Timeout: dh.pOpenOnuAc.KVStoreTimeout,
2392 PathPrefix: aBasePathKvStore}
Holger Hildebrandtc54939a2020-06-17 08:14:27 +00002393
mpagenkoaf801632020-07-03 10:00:42 +00002394 return kvbackend
Holger Hildebrandt24d51952020-05-04 14:03:42 +00002395}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002396func (dh *deviceHandler) getFlowOfbFields(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loMatchVlan *uint16,
Himani Chawla26e555c2020-08-31 12:30:20 +05302397 loAddPcp *uint8, loIPProto *uint32) {
mpagenkodff5dda2020-08-28 11:52:01 +00002398
mpagenkodff5dda2020-08-28 11:52:01 +00002399 for _, field := range flow.GetOfbFields(apFlowItem) {
2400 switch field.Type {
2401 case of.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
2402 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "flow type EthType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002404 "EthType": strconv.FormatInt(int64(field.GetEthType()), 16)})
2405 }
mpagenko01e726e2020-10-23 09:45:29 +00002406 /* TT related temporary workaround - should not be needed anymore
mpagenkodff5dda2020-08-28 11:52:01 +00002407 case of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
2408 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302409 *loIPProto = field.GetIpProto()
mpagenko01e726e2020-10-23 09:45:29 +00002410 logger.Debugw("flow type IpProto", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302411 "IpProto": strconv.FormatInt(int64(*loIPProto), 16)})
2412 if *loIPProto == 2 {
mpagenkodff5dda2020-08-28 11:52:01 +00002413 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2414 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002415 logger.Debugw("flow type IpProto 2: TT workaround: ignore flow",
2416 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302417 return
mpagenkodff5dda2020-08-28 11:52:01 +00002418 }
2419 }
mpagenko01e726e2020-10-23 09:45:29 +00002420 */
mpagenkodff5dda2020-08-28 11:52:01 +00002421 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
2422 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302423 *loMatchVlan = uint16(field.GetVlanVid())
mpagenkodff5dda2020-08-28 11:52:01 +00002424 loMatchVlanMask := uint16(field.GetVlanVidMask())
Himani Chawla26e555c2020-08-31 12:30:20 +05302425 if !(*loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) &&
mpagenkodff5dda2020-08-28 11:52:01 +00002426 loMatchVlanMask == uint16(of.OfpVlanId_OFPVID_PRESENT)) {
Himani Chawla26e555c2020-08-31 12:30:20 +05302427 *loMatchVlan = *loMatchVlan & 0xFFF // not transparent: copy only ID bits
mpagenkodff5dda2020-08-28 11:52:01 +00002428 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002429 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302430 "VID": strconv.FormatInt(int64(*loMatchVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002431 }
2432 case of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP:
2433 {
Himani Chawla26e555c2020-08-31 12:30:20 +05302434 *loAddPcp = uint8(field.GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002436 "PCP": loAddPcp})
2437 }
2438 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
2439 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002440 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002441 "UDP-DST": strconv.FormatInt(int64(field.GetUdpDst()), 16)})
2442 }
2443 case of.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
2444 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002446 "UDP-SRC": strconv.FormatInt(int64(field.GetUdpSrc()), 16)})
2447 }
2448 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_DST:
2449 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002450 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002451 "IPv4-DST": field.GetIpv4Dst()})
2452 }
2453 case of.OxmOfbFieldTypes_OFPXMT_OFB_IPV4_SRC:
2454 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002455 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002456 "IPv4-SRC": field.GetIpv4Src()})
2457 }
2458 case of.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
2459 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Debugw(ctx, "flow field type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002461 "Metadata": field.GetTableMetadata()})
2462 }
2463 /*
2464 default:
2465 {
2466 //all other entires ignored
2467 }
2468 */
2469 }
2470 } //for all OfbFields
Himani Chawla26e555c2020-08-31 12:30:20 +05302471}
mpagenkodff5dda2020-08-28 11:52:01 +00002472
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473func (dh *deviceHandler) getFlowActions(ctx context.Context, apFlowItem *ofp.OfpFlowStats, loSetPcp *uint8, loSetVlan *uint16) {
mpagenkodff5dda2020-08-28 11:52:01 +00002474 for _, action := range flow.GetActions(apFlowItem) {
2475 switch action.Type {
2476 /* not used:
2477 case of.OfpActionType_OFPAT_OUTPUT:
2478 {
mpagenko01e726e2020-10-23 09:45:29 +00002479 logger.Debugw("flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002480 "Output": action.GetOutput()})
2481 }
2482 */
2483 case of.OfpActionType_OFPAT_PUSH_VLAN:
2484 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "flow action type", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002486 "PushEthType": strconv.FormatInt(int64(action.GetPush().Ethertype), 16)})
2487 }
2488 case of.OfpActionType_OFPAT_SET_FIELD:
2489 {
2490 pActionSetField := action.GetSetField()
2491 if pActionSetField.Field.OxmClass != of.OfpOxmClass_OFPXMC_OPENFLOW_BASIC {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 logger.Warnw(ctx, "flow action SetField invalid OxmClass (ignored)", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002493 "OxcmClass": pActionSetField.Field.OxmClass})
2494 }
2495 if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID {
Himani Chawla26e555c2020-08-31 12:30:20 +05302496 *loSetVlan = uint16(pActionSetField.Field.GetOfbField().GetVlanVid())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Debugw(ctx, "flow Set VLAN from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302498 "SetVlan": strconv.FormatInt(int64(*loSetVlan), 16)})
mpagenkodff5dda2020-08-28 11:52:01 +00002499 } else if pActionSetField.Field.GetOfbField().Type == of.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_PCP {
Himani Chawla26e555c2020-08-31 12:30:20 +05302500 *loSetPcp = uint8(pActionSetField.Field.GetOfbField().GetVlanPcp())
dbainbri4d3a0dc2020-12-02 00:33:42 +00002501 logger.Debugw(ctx, "flow Set PCP from SetField action", log.Fields{"device-id": dh.deviceID,
Himani Chawla26e555c2020-08-31 12:30:20 +05302502 "SetPcp": *loSetPcp})
mpagenkodff5dda2020-08-28 11:52:01 +00002503 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002504 logger.Warnw(ctx, "flow action SetField invalid FieldType", log.Fields{"device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002505 "Type": pActionSetField.Field.GetOfbField().Type})
2506 }
2507 }
2508 /*
2509 default:
2510 {
2511 //all other entires ignored
2512 }
2513 */
2514 }
2515 } //for all Actions
Himani Chawla26e555c2020-08-31 12:30:20 +05302516}
2517
2518//addFlowItemToUniPort parses the actual flow item to add it to the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002519func (dh *deviceHandler) addFlowItemToUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
Himani Chawla26e555c2020-08-31 12:30:20 +05302520 var loSetVlan uint16 = uint16(of.OfpVlanId_OFPVID_NONE) //noValidEntry
2521 var loMatchVlan uint16 = uint16(of.OfpVlanId_OFPVID_PRESENT) //reserved VLANID entry
2522 var loAddPcp, loSetPcp uint8
2523 var loIPProto uint32
2524 /* the TechProfileId is part of the flow Metadata - compare also comment within
2525 * OLT-Adapter:openolt_flowmgr.go
2526 * Metadata 8 bytes:
2527 * Most Significant 2 Bytes = Inner VLAN
2528 * Next 2 Bytes = Tech Profile ID(TPID)
2529 * Least Significant 4 Bytes = Port ID
2530 * Flow Metadata carries Tech-Profile (TP) ID and is mandatory in all
2531 * subscriber related flows.
2532 */
2533
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 metadata := flow.GetMetadataFromWriteMetadataAction(ctx, apFlowItem)
Himani Chawla26e555c2020-08-31 12:30:20 +05302535 if metadata == 0 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Debugw(ctx, "flow-add invalid metadata - abort",
Himani Chawla26e555c2020-08-31 12:30:20 +05302537 log.Fields{"device-id": dh.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002538 return fmt.Errorf("flow-add invalid metadata: %s", dh.deviceID)
Himani Chawla26e555c2020-08-31 12:30:20 +05302539 }
mpagenko551a4d42020-12-08 18:09:20 +00002540 loTpID := uint8(flow.GetTechProfileIDFromWriteMetaData(ctx, metadata))
mpagenko01e726e2020-10-23 09:45:29 +00002541 loCookie := apFlowItem.GetCookie()
2542 loCookieSlice := []uint64{loCookie}
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Debugw(ctx, "flow-add base indications", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002544 "TechProf-Id": loTpID, "cookie": loCookie})
Himani Chawla26e555c2020-08-31 12:30:20 +05302545
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 dh.getFlowOfbFields(ctx, apFlowItem, &loMatchVlan, &loAddPcp, &loIPProto)
mpagenko01e726e2020-10-23 09:45:29 +00002547 /* TT related temporary workaround - should not be needed anymore
Himani Chawla26e555c2020-08-31 12:30:20 +05302548 if loIPProto == 2 {
2549 // some workaround for TT workflow at proto == 2 (IGMP trap) -> ignore the flow
2550 // avoids installing invalid EVTOCD rule
mpagenko01e726e2020-10-23 09:45:29 +00002551 logger.Debugw("flow-add type IpProto 2: TT workaround: ignore flow",
2552 log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302553 return nil
2554 }
mpagenko01e726e2020-10-23 09:45:29 +00002555 */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002556 dh.getFlowActions(ctx, apFlowItem, &loSetPcp, &loSetVlan)
mpagenkodff5dda2020-08-28 11:52:01 +00002557
2558 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 logger.Errorw(ctx, "flow-add aborted - SetVlanId undefined, but MatchVid set", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002560 "device-id": dh.deviceID, "UniPort": apUniPort.portNo,
2561 "set_vid": strconv.FormatInt(int64(loSetVlan), 16),
2562 "match_vid": strconv.FormatInt(int64(loMatchVlan), 16)})
2563 //TODO!!: Use DeviceId within the error response to rwCore
2564 // likewise also in other error response cases to calling components as requested in [VOL-3458]
mpagenko01e726e2020-10-23 09:45:29 +00002565 return fmt.Errorf("flow-add Set/Match VlanId inconsistent: %s", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002566 }
2567 if loSetVlan == uint16(of.OfpVlanId_OFPVID_NONE) && loMatchVlan == uint16(of.OfpVlanId_OFPVID_PRESENT) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 logger.Debugw(ctx, "flow-add vlan-any/copy", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002569 loSetVlan = loMatchVlan //both 'transparent' (copy any)
2570 } else {
2571 //looks like OMCI value 4097 (copyFromOuter - for Uni double tagged) is not supported here
2572 if loSetVlan != uint16(of.OfpVlanId_OFPVID_PRESENT) {
2573 // not set to transparent
Himani Chawla26e555c2020-08-31 12:30:20 +05302574 loSetVlan &= 0x0FFF //mask VID bits as prerequisite for vlanConfigFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002575 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 logger.Debugw(ctx, "flow-add vlan-set", log.Fields{"device-id": dh.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002577 }
mpagenko9a304ea2020-12-16 15:54:01 +00002578
2579 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002580 dh.lockVlanConfig.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002581 logger.Debugw(ctx, "flow-add got lock", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302582 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002583 err := dh.UniVlanConfigFsmMap[apUniPort.uniID].SetUniFlowParams(ctx, loTpID, loCookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +00002584 loMatchVlan, loSetVlan, loSetPcp)
mpagenkof1fc3862021-02-16 10:09:52 +00002585 dh.lockVlanConfig.RUnlock()
2586 return err
mpagenkodff5dda2020-08-28 11:52:01 +00002587 }
mpagenkof1fc3862021-02-16 10:09:52 +00002588 dh.lockVlanConfig.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 return dh.createVlanFilterFsm(ctx, apUniPort, loTpID, loCookieSlice,
mpagenkofc4f56e2020-11-04 17:17:49 +00002590 loMatchVlan, loSetVlan, loSetPcp, OmciVlanFilterAddDone)
mpagenko01e726e2020-10-23 09:45:29 +00002591}
2592
2593//removeFlowItemFromUniPort parses the actual flow item to remove it from the UniPort
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594func (dh *deviceHandler) removeFlowItemFromUniPort(ctx context.Context, apFlowItem *ofp.OfpFlowStats, apUniPort *onuUniPort) error {
mpagenko01e726e2020-10-23 09:45:29 +00002595 //optimization and assumption: the flow cookie uniquely identifies the flow and with that the internal rule
2596 //hence only the cookie is used here to find the relevant flow and possibly remove the rule
2597 //no extra check is done on the rule parameters
2598 //accordingly the removal is done only once - for the first found flow with that cookie, even though
2599 // at flow creation is not assured, that the same cookie is not configured for different flows - just assumed
2600 //additionally it is assumed here, that removal can only be done for one cookie per flow in a sequence (different
2601 // from addFlow - where at reconcilement multiple cookies per flow ) can be configured in one sequence)
mpagenkofc4f56e2020-11-04 17:17:49 +00002602 // - 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 +00002603 loCookie := apFlowItem.GetCookie()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002604 logger.Debugw(ctx, "flow-remove base indications", log.Fields{"device-id": dh.deviceID, "cookie": loCookie})
mpagenko01e726e2020-10-23 09:45:29 +00002605
2606 /* TT related temporary workaround - should not be needed anymore
2607 for _, field := range flow.GetOfbFields(apFlowItem) {
2608 if field.Type == of.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO {
2609 loIPProto := field.GetIpProto()
mpagenko551a4d42020-12-08 18:09:20 +00002610 logger.Debugw(ctx, "flow type IpProto", log.Fields{"device-id": dh.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002611 "IpProto": strconv.FormatInt(int64(loIPProto), 16)})
2612 if loIPProto == 2 {
2613 // 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 +00002614 logger.Debugw(ctx, "flow-remove type IpProto 2: TT workaround: ignore flow",
mpagenko01e726e2020-10-23 09:45:29 +00002615 log.Fields{"device-id": dh.deviceID})
2616 return nil
2617 }
2618 }
2619 } //for all OfbFields
2620 */
2621
mpagenko9a304ea2020-12-16 15:54:01 +00002622 //mutex protection as the update_flow rpc maybe running concurrently for different flows, perhaps also activities
mpagenkof1fc3862021-02-16 10:09:52 +00002623 dh.lockVlanConfig.RLock()
2624 defer dh.lockVlanConfig.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002625 if _, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 return dh.UniVlanConfigFsmMap[apUniPort.uniID].RemoveUniFlowParams(ctx, loCookie)
mpagenko01e726e2020-10-23 09:45:29 +00002627 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002628 logger.Debugw(ctx, "flow-remove called, but no flow is configured (no VlanConfigFsm, flow already removed) ",
mpagenko01e726e2020-10-23 09:45:29 +00002629 log.Fields{"device-id": dh.deviceID})
2630 //but as we regard the flow as not existing = removed we respond just ok
mpagenkofc4f56e2020-11-04 17:17:49 +00002631 // and treat the reason accordingly (which in the normal removal procedure is initiated by the FSM)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 go dh.deviceProcStatusUpdate(ctx, OmciVlanFilterRemDone)
mpagenkofc4f56e2020-11-04 17:17:49 +00002633
mpagenko01e726e2020-10-23 09:45:29 +00002634 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002635}
2636
Himani Chawla26e555c2020-08-31 12:30:20 +05302637// createVlanFilterFsm initializes and runs the VlanFilter FSM to transfer OMCI related VLAN config
mpagenko9a304ea2020-12-16 15:54:01 +00002638// if this function is called from possibly concurrent processes it must be mutex-protected from the caller!
mpagenko551a4d42020-12-08 18:09:20 +00002639func (dh *deviceHandler) createVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +00002640 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aDevEvent OnuDeviceEvent) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002641 chVlanFilterFsm := make(chan Message, 2048)
2642
dbainbri4d3a0dc2020-12-02 00:33:42 +00002643 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
mpagenkodff5dda2020-08-28 11:52:01 +00002644 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002645 logger.Errorw(ctx, "No valid OnuDevice -aborting", log.Fields{"device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302646 return fmt.Errorf("no valid OnuDevice for device-id %x - aborting", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002647 }
2648
dbainbri4d3a0dc2020-12-02 00:33:42 +00002649 pVlanFilterFsm := NewUniVlanConfigFsm(ctx, dh, pDevEntry.PDevOmciCC, apUniPort, dh.pOnuTP,
mpagenko01e726e2020-10-23 09:45:29 +00002650 pDevEntry.pOnuDB, aTpID, aDevEvent, "UniVlanConfigFsm", chVlanFilterFsm,
2651 dh.pOpenOnuAc.AcceptIncrementalEvto, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
mpagenkodff5dda2020-08-28 11:52:01 +00002652 if pVlanFilterFsm != nil {
mpagenkof1fc3862021-02-16 10:09:52 +00002653 dh.lockVlanConfig.Lock()
mpagenko7d6bb022021-03-11 15:07:55 +00002654 //ensure the mutex is locked throughout the state transition to 'starting' to prevent unintended (ignored) events to be sent there
2655 // (from parallel processing)
2656 defer dh.lockVlanConfig.Unlock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302657 dh.UniVlanConfigFsmMap[apUniPort.uniID] = pVlanFilterFsm
mpagenkodff5dda2020-08-28 11:52:01 +00002658 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2659 if pVlanFilterStatemachine != nil {
2660 if pVlanFilterStatemachine.Is(vlanStDisabled) {
2661 if err := pVlanFilterStatemachine.Event(vlanEvStart); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002662 logger.Warnw(ctx, "UniVlanConfigFsm: can't start", log.Fields{"err": err})
Himani Chawla26e555c2020-08-31 12:30:20 +05302663 return fmt.Errorf("can't start UniVlanConfigFsm for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002664 }
Himani Chawla26e555c2020-08-31 12:30:20 +05302665 /***** UniVlanConfigFsm started */
dbainbri4d3a0dc2020-12-02 00:33:42 +00002666 logger.Debugw(ctx, "UniVlanConfigFsm started", log.Fields{
Himani Chawla26e555c2020-08-31 12:30:20 +05302667 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2668 "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002669 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002670 logger.Warnw(ctx, "wrong state of UniVlanConfigFsm - want: disabled", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002671 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302672 return fmt.Errorf("uniVlanConfigFsm not in expected disabled state for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002673 }
2674 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002675 logger.Errorw(ctx, "UniVlanConfigFsm StateMachine invalid - cannot be executed!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002676 "device-id": dh.deviceID})
Himani Chawla26e555c2020-08-31 12:30:20 +05302677 return fmt.Errorf("uniVlanConfigFsm invalid for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002678 }
2679 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002680 logger.Errorw(ctx, "UniVlanConfigFsm could not be created - abort!!", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002681 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
Himani Chawla26e555c2020-08-31 12:30:20 +05302682 return fmt.Errorf("uniVlanConfigFsm could not be created for device-id %x", dh.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002683 }
2684 return nil
2685}
2686
mpagenkofc4f56e2020-11-04 17:17:49 +00002687//VerifyVlanConfigRequest checks on existence of a given uniPort
2688// and starts verification of flow config based on that
mpagenko551a4d42020-12-08 18:09:20 +00002689func (dh *deviceHandler) VerifyVlanConfigRequest(ctx context.Context, aUniID uint8, aTpID uint8) {
mpagenkofc4f56e2020-11-04 17:17:49 +00002690 //ensure that the given uniID is available (configured) in the UniPort class (used for OMCI entities)
2691 var pCurrentUniPort *onuUniPort
2692 for _, uniPort := range dh.uniEntityMap {
2693 // only if this port is validated for operState transfer
2694 if uniPort.uniID == uint8(aUniID) {
2695 pCurrentUniPort = uniPort
2696 break //found - end search loop
2697 }
2698 }
2699 if pCurrentUniPort == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002700 logger.Debugw(ctx, "VerifyVlanConfig aborted: requested uniID not found in PortDB",
mpagenkofc4f56e2020-11-04 17:17:49 +00002701 log.Fields{"device-id": dh.deviceID, "uni-id": aUniID})
2702 return
2703 }
mpagenko551a4d42020-12-08 18:09:20 +00002704 dh.verifyUniVlanConfigRequest(ctx, pCurrentUniPort, aTpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00002705}
2706
mpagenkodff5dda2020-08-28 11:52:01 +00002707//verifyUniVlanConfigRequest checks on existence of flow configuration and starts it accordingly
mpagenko551a4d42020-12-08 18:09:20 +00002708func (dh *deviceHandler) verifyUniVlanConfigRequest(ctx context.Context, apUniPort *onuUniPort, aTpID uint8) {
mpagenkodff5dda2020-08-28 11:52:01 +00002709 //TODO!! verify and start pending flow configuration
2710 //some pending config request my exist in case the UniVlanConfig FSM was already started - with internal data -
2711 //but execution was set to 'on hold' as first the TechProfile config had to be applied
mpagenkof1fc3862021-02-16 10:09:52 +00002712
2713 dh.lockVlanConfig.RLock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302714 if pVlanFilterFsm, exist := dh.UniVlanConfigFsmMap[apUniPort.uniID]; exist {
mpagenkof1fc3862021-02-16 10:09:52 +00002715 dh.lockVlanConfig.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002716 //VlanFilterFsm exists and was already started (assumed to wait for TechProfile execution here)
2717 pVlanFilterStatemachine := pVlanFilterFsm.pAdaptFsm.pFsm
2718 if pVlanFilterStatemachine != nil {
mpagenko551a4d42020-12-08 18:09:20 +00002719 //if this was an event of the TP processing that was waited for in the VlanFilterFsm
2720 if pVlanFilterFsm.GetWaitingTpID() == aTpID {
2721 if pVlanFilterStatemachine.Is(vlanStWaitingTechProf) {
2722 if err := pVlanFilterStatemachine.Event(vlanEvContinueConfig); err != nil {
2723 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2724 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2725 } else {
2726 /***** UniVlanConfigFsm continued */
2727 logger.Debugw(ctx, "UniVlanConfigFsm continued", log.Fields{
2728 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2729 "UniPort": apUniPort.portNo})
2730 }
2731 } else if pVlanFilterStatemachine.Is(vlanStIncrFlowWaitTP) {
2732 if err := pVlanFilterStatemachine.Event(vlanEvIncrFlowConfig); err != nil {
2733 logger.Warnw(ctx, "UniVlanConfigFsm: can't continue processing", log.Fields{"err": err,
2734 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
2735 } else {
2736 /***** UniVlanConfigFsm continued */
2737 logger.Debugw(ctx, "UniVlanConfigFsm continued with incremental flow", log.Fields{
2738 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2739 "UniPort": apUniPort.portNo})
2740 }
mpagenkodff5dda2020-08-28 11:52:01 +00002741 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002742 logger.Debugw(ctx, "no state of UniVlanConfigFsm to be continued", log.Fields{
2743 "have": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002744 "UniPort": apUniPort.portNo})
2745 }
2746 } else {
mpagenko551a4d42020-12-08 18:09:20 +00002747 logger.Debugw(ctx, "TechProfile Ready event for TpId that was not waited for in the VlanConfigFsm - continue waiting", log.Fields{
2748 "state": pVlanFilterStatemachine.Current(), "device-id": dh.deviceID,
2749 "UniPort": apUniPort.portNo, "techprofile-id (done)": aTpID})
mpagenkodff5dda2020-08-28 11:52:01 +00002750 }
2751 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002752 logger.Debugw(ctx, "UniVlanConfigFsm StateMachine does not exist, no flow processing", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00002753 "device-id": dh.deviceID, "UniPort": apUniPort.portNo})
mpagenkodff5dda2020-08-28 11:52:01 +00002754 }
mpagenkof1fc3862021-02-16 10:09:52 +00002755 } else {
2756 dh.lockVlanConfig.RUnlock()
2757 }
mpagenkodff5dda2020-08-28 11:52:01 +00002758}
2759
2760//RemoveVlanFilterFsm deletes the stored pointer to the VlanConfigFsm
2761// 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 +00002762func (dh *deviceHandler) RemoveVlanFilterFsm(ctx context.Context, apUniPort *onuUniPort) {
2763 logger.Debugw(ctx, "remove UniVlanConfigFsm StateMachine", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00002764 "device-id": dh.deviceID, "uniPort": apUniPort.portNo})
2765 //save to do, even if entry dows not exist
mpagenkof1fc3862021-02-16 10:09:52 +00002766 dh.lockVlanConfig.Lock()
Himani Chawla26e555c2020-08-31 12:30:20 +05302767 delete(dh.UniVlanConfigFsmMap, apUniPort.uniID)
mpagenkof1fc3862021-02-16 10:09:52 +00002768 dh.lockVlanConfig.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002769}
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002770
mpagenkof1fc3862021-02-16 10:09:52 +00002771//startWritingOnuDataToKvStore initiates the KVStore write of ONU persistent data
2772func (dh *deviceHandler) startWritingOnuDataToKvStore(ctx context.Context, aPDevEntry *OnuDeviceEntry) error {
2773 dh.mutexKvStoreContext.Lock() //this write routine may (could) be called with the same context,
2774 defer dh.mutexKvStoreContext.Unlock() //this write routine may (could) be called with the same context,
2775 // obviously then parallel processing on the cancel must be avoided
2776 // deadline context to ensure completion of background routines waited for
2777 //20200721: 10s proved to be less in 8*8 ONU test on local vbox machine with debug, might be further adapted
2778 deadline := time.Now().Add(dh.pOpenOnuAc.maxTimeoutInterAdapterComm) //allowed run time to finish before execution
2779 dctx, cancel := context.WithDeadline(context.Background(), deadline)
2780
2781 aPDevEntry.resetKvProcessingErrorIndication()
2782 var wg sync.WaitGroup
2783 wg.Add(1) // for the 1 go routine to finish
2784
2785 go aPDevEntry.updateOnuKvStore(log.WithSpanFromContext(dctx, ctx), &wg)
2786 dh.waitForCompletion(ctx, cancel, &wg, "UpdateKvStore") //wait for background process to finish
2787
2788 return aPDevEntry.getKvProcessingErrorIndication()
2789}
2790
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002791//storePersUniFlowConfig updates local storage of OnuUniFlowConfig and writes it into kv-store afterwards to have it
2792//available for potential reconcilement
mpagenkof1fc3862021-02-16 10:09:52 +00002793func (dh *deviceHandler) storePersUniFlowConfig(ctx context.Context, aUniID uint8,
2794 aUniVlanFlowParams *[]uniVlanFlowParams, aWriteToKvStore bool) error {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002795
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00002796 if dh.isReconciling() {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797 logger.Debugw(ctx, "reconciling - don't store persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002798 return nil
2799 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800 logger.Debugw(ctx, "Store or clear persistent UniFlowConfig", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002801
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002803 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Errorw(ctx, "No valid OnuDevice - aborting", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002805 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2806 }
2807 pDevEntry.updateOnuUniFlowConfig(aUniID, aUniVlanFlowParams)
2808
mpagenkof1fc3862021-02-16 10:09:52 +00002809 if aWriteToKvStore {
2810 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
2811 }
2812 return nil
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002813}
2814
dbainbri4d3a0dc2020-12-02 00:33:42 +00002815func (dh *deviceHandler) waitForCompletion(ctx context.Context, cancel context.CancelFunc, wg *sync.WaitGroup, aCallerIdent string) {
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002816 defer cancel() //ensure termination of context (may be pro forma)
2817 wg.Wait()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002818 logger.Debugw(ctx, "WaitGroup processing completed", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002819 "device-id": dh.deviceID, "called from": aCallerIdent})
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002820}
2821
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822func (dh *deviceHandler) deviceReasonUpdate(ctx context.Context, deviceReason uint8, notifyCore bool) error {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002823
Holger Hildebrandtbe523842021-03-10 10:47:18 +00002824 dh.setDeviceReason(deviceReason)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002825 if notifyCore {
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002826 //TODO with VOL-3045/VOL-3046: return the error and stop further processing at calling position
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827 if err := dh.coreProxy.DeviceReasonUpdate(log.WithSpanFromContext(context.TODO(), ctx), dh.deviceID, deviceReasonMap[deviceReason]); err != nil {
2828 logger.Errorf(ctx, "DeviceReasonUpdate error: %s",
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002829 log.Fields{"device-id": dh.deviceID, "error": err}, deviceReasonMap[deviceReason])
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002830 return err
2831 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832 logger.Infof(ctx, "DeviceReasonUpdate success: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002833 return nil
2834 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002835 logger.Infof(ctx, "Don't notify core about DeviceReasonUpdate: %s - device-id: %s", deviceReasonMap[deviceReason], dh.deviceID)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002836 return nil
2837}
2838
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839func (dh *deviceHandler) storePersistentData(ctx context.Context) error {
2840 pDevEntry := dh.getOnuDeviceEntry(ctx, true)
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002841 if pDevEntry == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002842 logger.Warnw(ctx, "No valid OnuDevice", log.Fields{"device-id": dh.deviceID})
Holger Hildebrandt3a644642020-12-02 09:46:18 +00002843 return fmt.Errorf("no valid OnuDevice: %s", dh.deviceID)
2844 }
mpagenkof1fc3862021-02-16 10:09:52 +00002845 return dh.startWritingOnuDataToKvStore(ctx, pDevEntry)
Holger Hildebrandt80129db2020-11-23 10:49:32 +00002846}
2847
Holger Hildebrandt47555e72020-09-21 11:07:24 +00002848func (dh *deviceHandler) combineErrorStrings(errS ...error) error {
2849 var errStr string = ""
2850 for _, err := range errS {
2851 if err != nil {
2852 errStr = errStr + err.Error() + " "
2853 }
2854 }
2855 if errStr != "" {
2856 return fmt.Errorf("%s: %s", errStr, dh.deviceID)
2857 }
2858 return nil
2859}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860
2861// getUniPortMEEntityID takes uniPortNo as the input and returns the Entity ID corresponding to this UNI-G ME Instance
2862func (dh *deviceHandler) getUniPortMEEntityID(uniPortNo uint32) (uint16, error) {
2863 dh.lockDevice.RLock()
2864 defer dh.lockDevice.RUnlock()
2865 if uniPort, ok := dh.uniEntityMap[uniPortNo]; ok {
2866 return uniPort.entityID, nil
2867 }
2868 return 0, errors.New("error-fetching-uni-port")
2869}
Girish Gowdrae09a6202021-01-12 18:10:59 -08002870
2871// updatePmConfig updates the pm metrics config.
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002872func (dh *deviceHandler) updatePmConfig(ctx context.Context, pmConfigs *voltha.PmConfigs) error {
2873 var errorsList []error
2874 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 -08002875
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002876 errorsList = append(dh.handleGlobalPmConfigUpdates(ctx, pmConfigs), errorsList...)
2877 errorsList = append(dh.handleGroupPmConfigUpdates(ctx, pmConfigs), errorsList...)
2878 errorsList = append(dh.handleStandalonePmConfigUpdates(ctx, pmConfigs), errorsList...)
2879
2880 // Note that if more than one pm config field is updated in a given call, it is possible that partial pm config is handled
2881 // successfully.
2882 // TODO: Although it is possible to revert to old config in case of partial failure, the code becomes quite complex. Needs more investigation
2883 // Is it possible the rw-core reverts to old config on partial failure but adapter retains a partial new config?
2884 if len(errorsList) > 0 {
2885 logger.Errorw(ctx, "one-or-more-pm-config-failed", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2886 return fmt.Errorf("errors-handling-one-or-more-pm-config, errors:%v", errorsList)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002887 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002888 logger.Infow(ctx, "pm-config-updated", log.Fields{"device-id": dh.deviceID, "pmConfig": dh.pmConfigs})
2889 return nil
Girish Gowdrae09a6202021-01-12 18:10:59 -08002890}
2891
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002892func (dh *deviceHandler) handleGlobalPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2893 var err error
2894 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002895 logger.Infow(ctx, "handling-global-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002896
2897 if pmConfigs.DefaultFreq != dh.pmConfigs.DefaultFreq {
2898 if err = dh.pOnuMetricsMgr.updateDefaultFrequency(ctx, pmConfigs); err != nil {
2899 errorsList = append(errorsList, err)
2900 }
2901 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002902 logger.Infow(ctx, "handling-global-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
mpagenko15ff4a52021-03-02 10:09:20 +00002903
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002904 return errorsList
2905}
2906
2907func (dh *deviceHandler) handleGroupPmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2908 var err error
2909 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002910 logger.Debugw(ctx, "handling-group-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002911 // Check if group metric related config is updated
2912 for _, v := range pmConfigs.Groups {
2913 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
2914 m, ok := dh.pOnuMetricsMgr.groupMetricMap[v.GroupName]
2915 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2916
2917 if ok && m.frequency != v.GroupFreq {
2918 if err = dh.pOnuMetricsMgr.updateGroupFreq(ctx, v.GroupName, pmConfigs); err != nil {
2919 errorsList = append(errorsList, err)
2920 }
2921 }
2922 if ok && m.enabled != v.Enabled {
2923 if err = dh.pOnuMetricsMgr.updateGroupSupport(ctx, v.GroupName, pmConfigs); err != nil {
2924 errorsList = append(errorsList, err)
2925 }
2926 }
2927 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002928 logger.Debugw(ctx, "handling-group-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002929 return errorsList
2930}
2931
2932func (dh *deviceHandler) handleStandalonePmConfigUpdates(ctx context.Context, pmConfigs *voltha.PmConfigs) []error {
2933 var err error
2934 var errorsList []error
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002935 logger.Debugw(ctx, "handling-individual-pm-config-params - start", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002936 // Check if standalone metric related config is updated
2937 for _, v := range pmConfigs.Metrics {
2938 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock()
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002939 m, ok := dh.pOnuMetricsMgr.standaloneMetricMap[v.Name]
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002940 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
2941
2942 if ok && m.frequency != v.SampleFreq {
2943 if err = dh.pOnuMetricsMgr.updateMetricFreq(ctx, v.Name, pmConfigs); err != nil {
2944 errorsList = append(errorsList, err)
2945 }
2946 }
2947 if ok && m.enabled != v.Enabled {
2948 if err = dh.pOnuMetricsMgr.updateMetricSupport(ctx, v.Name, pmConfigs); err != nil {
2949 errorsList = append(errorsList, err)
2950 }
2951 }
2952 }
Girish Gowdra36ccf7d2021-02-25 20:42:51 -08002953 logger.Debugw(ctx, "handling-individual-pm-config-params - done", log.Fields{"device-id": dh.device.Id})
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002954 return errorsList
2955}
2956
2957// nolint: gocyclo
Girish Gowdrae09a6202021-01-12 18:10:59 -08002958func (dh *deviceHandler) startCollector(ctx context.Context) {
2959 logger.Debugf(ctx, "startingCollector")
2960
2961 // Start routine to process OMCI GET Responses
2962 go dh.pOnuMetricsMgr.processOmciMessages(ctx)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002963 // Initialize the next metric collection time.
2964 // Normally done when the onu_metrics_manager is initialized the first time, but needed again later when ONU is
2965 // reset like onu rebooted.
2966 dh.pOnuMetricsMgr.initializeMetricCollectionTime(ctx)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002967 dh.setCollectorIsRunning(true)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002968 for {
2969 select {
2970 case <-dh.stopCollector:
Holger Hildebrandt10d98192021-01-27 15:29:31 +00002971 dh.setCollectorIsRunning(false)
Girish Gowdrae09a6202021-01-12 18:10:59 -08002972 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Girish Gowdrae0140f02021-02-02 16:55:09 -08002973 // Stop the L2 PM FSM
2974 go func() {
2975 if dh.pOnuMetricsMgr.pAdaptFsm != nil && dh.pOnuMetricsMgr.pAdaptFsm.pFsm != nil {
2976 if err := dh.pOnuMetricsMgr.pAdaptFsm.pFsm.Event(l2PmEventStop); err != nil {
2977 logger.Errorw(ctx, "error calling event", log.Fields{"device-id": dh.deviceID, "err": err})
2978 }
2979 } else {
2980 logger.Errorw(ctx, "metrics manager fsm not initialized", log.Fields{"device-id": dh.deviceID})
2981 }
2982 }()
Girish Gowdra7b0ee5c2021-03-19 21:48:15 -07002983 if dh.pOnuMetricsMgr.getOmciProcessingStatus() {
2984 dh.pOnuMetricsMgr.stopProcessingOmciResponses <- true // Stop the OMCI GET response processing routine
2985 }
2986 if dh.pOnuMetricsMgr.getTickGenerationStatus() {
2987 dh.pOnuMetricsMgr.stopTicks <- true
2988 }
Girish Gowdrae0140f02021-02-02 16:55:09 -08002989
Girish Gowdrae09a6202021-01-12 18:10:59 -08002990 return
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002991 case <-time.After(time.Duration(FrequencyGranularity) * time.Second): // Check every FrequencyGranularity to see if it is time for collecting metrics
2992 if !dh.pmConfigs.FreqOverride { // If FreqOverride is false, then nextGlobalMetricCollectionTime applies
2993 // If the current time is eqaul to or greater than the nextGlobalMetricCollectionTime, collect the group and standalone metrics
2994 if time.Now().Equal(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) || time.Now().After(dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime) {
2995 go dh.pOnuMetricsMgr.collectAllGroupAndStandaloneMetrics(ctx)
Girish Gowdraaf0ad632021-01-27 13:00:01 -08002996 // Update the next metric collection time.
2997 dh.pOnuMetricsMgr.nextGlobalMetricCollectionTime = time.Now().Add(time.Duration(dh.pmConfigs.DefaultFreq) * time.Second)
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002998 }
Girish Gowdra5a7c4922021-01-22 18:33:41 -08002999 } else {
3000 if dh.pmConfigs.Grouped { // metrics are managed as a group
3001 // parse through the group and standalone metrics to see it is time to collect their metrics
3002 dh.pOnuMetricsMgr.onuMetricsManagerLock.RLock() // Rlock as we are reading groupMetricMap and standaloneMetricMap
Girish Gowdrae09a6202021-01-12 18:10:59 -08003003
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003004 for n, g := range dh.pOnuMetricsMgr.groupMetricMap {
3005 // 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 -08003006 // Since the L2 PM counters are collected in a separate FSM, we should avoid those counters in the check.
3007 if g.enabled && !g.isL2PMCounter && (time.Now().Equal(g.nextCollectionInterval) || time.Now().After(g.nextCollectionInterval)) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003008 go dh.pOnuMetricsMgr.collectGroupMetric(ctx, n)
3009 }
3010 }
3011 for n, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3012 // If the standalone is enabled AND (current time is equal to OR after nextCollectionInterval, collect the metric)
3013 if m.enabled && (time.Now().Equal(m.nextCollectionInterval) || time.Now().After(m.nextCollectionInterval)) {
3014 go dh.pOnuMetricsMgr.collectStandaloneMetric(ctx, n)
3015 }
3016 }
3017 dh.pOnuMetricsMgr.onuMetricsManagerLock.RUnlock()
3018
3019 // parse through the group and update the next metric collection time
3020 dh.pOnuMetricsMgr.onuMetricsManagerLock.Lock() // Lock as we are writing the next metric collection time
3021 for _, g := range dh.pOnuMetricsMgr.groupMetricMap {
3022 // 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 -08003023 // Since the L2 PM counters are collected and managed in a separate FSM, we should avoid those counters in the check.
3024 if g.enabled && !g.isL2PMCounter && (g.nextCollectionInterval.Before(time.Now()) || g.nextCollectionInterval.Equal(time.Now())) {
Girish Gowdra5a7c4922021-01-22 18:33:41 -08003025 g.nextCollectionInterval = time.Now().Add(time.Duration(g.frequency) * time.Second)
3026 }
3027 }
3028 // parse through the standalone metrics and update the next metric collection time
3029 for _, m := range dh.pOnuMetricsMgr.standaloneMetricMap {
3030 // If standalone metrics enabled, and the nextCollectionInterval is old (before or equal to current time), update the next collection time stamp
3031 if m.enabled && (m.nextCollectionInterval.Before(time.Now()) || m.nextCollectionInterval.Equal(time.Now())) {
3032 m.nextCollectionInterval = time.Now().Add(time.Duration(m.frequency) * time.Second)
3033 }
3034 }
3035 dh.pOnuMetricsMgr.onuMetricsManagerLock.Unlock()
3036 } /* else { // metrics are not managed as a group
3037 // TODO: We currently do not have standalone metrics. When available, add code here to fetch the metric.
3038 } */
3039 }
Girish Gowdrae09a6202021-01-12 18:10:59 -08003040 }
3041 }
3042}
kesavandfdf77632021-01-26 23:40:33 -05003043
3044func (dh *deviceHandler) getUniPortStatus(ctx context.Context, uniInfo *extension.GetOnuUniInfoRequest) *extension.SingleGetValueResponse {
3045
3046 portStatus := NewUniPortStatus(dh.pOnuOmciDevice.PDevOmciCC)
3047 return portStatus.getUniPortStatus(ctx, uniInfo.UniIndex)
3048}
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003049
mpagenkof1fc3862021-02-16 10:09:52 +00003050func (dh *deviceHandler) isFsmInOmciIdleState(ctx context.Context, pFsm *fsm.FSM, wantedState string) bool {
3051 if pFsm == nil {
3052 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003053 }
mpagenkof1fc3862021-02-16 10:09:52 +00003054 return pFsm.Current() == wantedState
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003055}
3056
mpagenkof1fc3862021-02-16 10:09:52 +00003057func (dh *deviceHandler) isFsmInOmciIdleStateDefault(ctx context.Context, omciFsm usedOmciConfigFsms, wantedState string) bool {
3058 var pFsm *fsm.FSM
3059 //note/TODO!!: might be that access to all these specific FSM; pointers need a semaphore protection as well, cmp lockUpgradeFsm
3060 switch omciFsm {
3061 case cUploadFsm:
3062 {
3063 pFsm = dh.pOnuOmciDevice.pMibUploadFsm.pFsm
3064 }
3065 case cDownloadFsm:
3066 {
3067 pFsm = dh.pOnuOmciDevice.pMibDownloadFsm.pFsm
3068 }
3069 case cUniLockFsm:
3070 {
3071 pFsm = dh.pLockStateFsm.pAdaptFsm.pFsm
3072 }
3073 case cUniUnLockFsm:
3074 {
3075 pFsm = dh.pUnlockStateFsm.pAdaptFsm.pFsm
3076 }
3077 case cL2PmFsm:
3078 {
3079 if dh.pOnuMetricsMgr != nil && dh.pOnuMetricsMgr.pAdaptFsm != nil {
3080 pFsm = dh.pOnuMetricsMgr.pAdaptFsm.pFsm
3081 } else {
3082 return true //FSM not active - so there is no activity on omci
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003083 }
3084 }
mpagenko80622a52021-02-09 16:53:23 +00003085 case cOnuUpgradeFsm:
3086 {
3087 dh.lockUpgradeFsm.RLock()
3088 defer dh.lockUpgradeFsm.RUnlock()
3089 pFsm = dh.pOnuUpradeFsm.pAdaptFsm.pFsm
3090 }
mpagenkof1fc3862021-02-16 10:09:52 +00003091 default:
3092 {
3093 logger.Errorw(ctx, "invalid stateMachine selected for idle check", log.Fields{
3094 "device-id": dh.deviceID, "selectedFsm number": omciFsm})
3095 return false //logical error in FSM check, do not not indicate 'idle' - we can't be sure
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003096 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003097 }
mpagenkof1fc3862021-02-16 10:09:52 +00003098 return dh.isFsmInOmciIdleState(ctx, pFsm, wantedState)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003099}
3100
mpagenkof1fc3862021-02-16 10:09:52 +00003101func (dh *deviceHandler) isAniConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3102 for _, v := range dh.pOnuTP.pAniConfigFsm {
3103 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003104 return false
3105 }
3106 }
3107 return true
3108}
3109
mpagenkof1fc3862021-02-16 10:09:52 +00003110func (dh *deviceHandler) isUniVlanConfigFsmInOmciIdleState(ctx context.Context, omciFsm usedOmciConfigFsms, idleState string) bool {
3111 dh.lockVlanConfig.RLock()
3112 defer dh.lockVlanConfig.RUnlock()
3113 for _, v := range dh.UniVlanConfigFsmMap {
3114 if !dh.isFsmInOmciIdleState(ctx, v.pAdaptFsm.pFsm, idleState) {
3115 return false
3116 }
3117 }
3118 return true //FSM not active - so there is no activity on omci
3119}
3120
3121func (dh *deviceHandler) checkUserServiceExists(ctx context.Context) bool {
3122 dh.lockVlanConfig.RLock()
3123 defer dh.lockVlanConfig.RUnlock()
3124 for _, v := range dh.UniVlanConfigFsmMap {
3125 if v.pAdaptFsm.pFsm != nil {
3126 if v.pAdaptFsm.pFsm.Is(cVlanFsmConfiguredState) {
3127 return true //there is at least one VLAN FSM with some active configuration
3128 }
3129 }
3130 }
3131 return false //there is no VLAN FSM with some active configuration
3132}
3133
3134func (dh *deviceHandler) checkAuditStartCondition(ctx context.Context, callingFsm usedOmciConfigFsms) bool {
3135 for fsmName, fsmStruct := range fsmOmciIdleStateFuncMap {
3136 if fsmName != callingFsm && !fsmStruct.omciIdleCheckFunc(dh, ctx, fsmName, fsmStruct.omciIdleState) {
3137 return false
3138 }
3139 }
3140 // a further check is done to identify, if at least some data traffic related configuration exists
3141 // 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])
3142 return dh.checkUserServiceExists(ctx)
3143}
3144
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003145func (dh *deviceHandler) prepareReconcilingWithActiveAdapter(ctx context.Context) {
3146 logger.Debugw(ctx, "prepare to reconcile the ONU with adapter using persistency data", log.Fields{"device-id": dh.device.Id})
3147 if err := dh.resetFsms(ctx, false); err != nil {
3148 logger.Errorw(ctx, "reset of FSMs failed!", log.Fields{"device-id": dh.deviceID, "error": err})
3149 // TODO: fatal error reset ONU, delete deviceHandler!
3150 return
3151 }
3152 if !dh.getCollectorIsRunning() {
3153 // Start PM collector routine
3154 go dh.startCollector(ctx)
3155 }
Himani Chawla1472c682021-03-17 17:11:14 +05303156 if !dh.getAlarmManagerIsRunning(ctx) {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303157 go dh.startAlarmManager(ctx)
3158 }
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003159 dh.uniEntityMap = make(map[uint32]*onuUniPort)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003160 dh.startReconciling(ctx, false)
Holger Hildebrandt10d98192021-01-27 15:29:31 +00003161}
3162
3163func (dh *deviceHandler) setCollectorIsRunning(flagValue bool) {
3164 dh.mutexCollectorFlag.Lock()
3165 dh.collectorIsRunning = flagValue
3166 dh.mutexCollectorFlag.Unlock()
3167}
3168
3169func (dh *deviceHandler) getCollectorIsRunning() bool {
3170 dh.mutexCollectorFlag.RLock()
3171 flagValue := dh.collectorIsRunning
3172 dh.mutexCollectorFlag.RUnlock()
3173 return flagValue
3174}
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303175
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303176func (dh *deviceHandler) setAlarmManagerIsRunning(flagValue bool) {
3177 dh.mutextAlarmManagerFlag.Lock()
3178 dh.alarmManagerIsRunning = flagValue
3179 dh.mutextAlarmManagerFlag.Unlock()
3180}
3181
Himani Chawla1472c682021-03-17 17:11:14 +05303182func (dh *deviceHandler) getAlarmManagerIsRunning(ctx context.Context) bool {
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303183 dh.mutextAlarmManagerFlag.RLock()
3184 flagValue := dh.alarmManagerIsRunning
Himani Chawla1472c682021-03-17 17:11:14 +05303185 logger.Debugw(ctx, "alarm-manager-is-running", log.Fields{"flag": dh.alarmManagerIsRunning})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303186 dh.mutextAlarmManagerFlag.RUnlock()
3187 return flagValue
3188}
3189
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303190func (dh *deviceHandler) startAlarmManager(ctx context.Context) {
3191 logger.Debugf(ctx, "startingAlarmManager")
3192
3193 // Start routine to process OMCI GET Responses
3194 go dh.pAlarmMgr.startOMCIAlarmMessageProcessing(ctx)
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303195 dh.setAlarmManagerIsRunning(true)
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303196 if stop := <-dh.stopAlarmManager; stop {
3197 logger.Debugw(ctx, "stopping-collector-for-onu", log.Fields{"device-id": dh.device.Id})
Himani Chawla4c1d4c72021-02-18 12:14:31 +05303198 dh.setAlarmManagerIsRunning(false)
Himani Chawlad3dac422021-03-13 02:31:31 +05303199 go func() {
Himani Chawla1472c682021-03-17 17:11:14 +05303200 if dh.pAlarmMgr.alarmSyncFsm != nil && dh.pAlarmMgr.alarmSyncFsm.pFsm != nil {
3201 _ = dh.pAlarmMgr.alarmSyncFsm.pFsm.Event(asEvStop)
3202 }
Himani Chawlad3dac422021-03-13 02:31:31 +05303203 }()
Himani Chawlad3dac422021-03-13 02:31:31 +05303204 dh.pAlarmMgr.stopProcessingOmciMessages <- true // Stop the OMCI routines if any(This will stop the fsms also)
Himani Chawla1472c682021-03-17 17:11:14 +05303205 dh.pAlarmMgr.stopAlarmAuditTimer <- struct{}{}
3206 logger.Debugw(ctx, "sent-all-stop-signals-to-alarm-manager", log.Fields{"device-id": dh.device.Id})
Himani Chawlaac1f5ad2021-02-04 21:21:54 +05303207 }
3208}
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003209
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003210func (dh *deviceHandler) startReconciling(ctx context.Context, skipOnuConfig bool) {
Holger Hildebrandtbdc5f002021-04-19 14:46:21 +00003211 logger.Debugw(ctx, "start reconciling", log.Fields{"skipOnuConfig": skipOnuConfig, "device-id": dh.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003212
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003213 if !dh.isReconciling() {
3214 go func() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003215 logger.Debugw(ctx, "wait for channel signal or timeout",
3216 log.Fields{"timeout": dh.pOpenOnuAc.maxTimeoutReconciling, "device-id": dh.deviceID})
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003217 select {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003218 case success := <-dh.chReconcilingFinished:
3219 if success {
3220 logger.Debugw(ctx, "reconciling has been finished in time",
3221 log.Fields{"device-id": dh.deviceID})
3222 } else {
3223 logger.Debugw(ctx, "wait for reconciling aborted",
3224 log.Fields{"device-id": dh.deviceID})
3225 }
Holger Hildebrandt38985dc2021-02-18 16:25:20 +00003226 case <-time.After(dh.pOpenOnuAc.maxTimeoutReconciling):
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003227 logger.Errorw(ctx, "timeout waiting for reconciling to be finished!",
3228 log.Fields{"device-id": dh.deviceID})
3229 }
3230 dh.mutexReconcilingFlag.Lock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003231 dh.reconciling = cNoReconciling
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003232 dh.mutexReconcilingFlag.Unlock()
3233 }()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003234 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003235 dh.mutexReconcilingFlag.Lock()
3236 if skipOnuConfig {
3237 dh.reconciling = cSkipOnuConfigReconciling
3238 } else {
3239 dh.reconciling = cOnuConfigReconciling
3240 }
3241 dh.mutexReconcilingFlag.Unlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003242}
3243
3244func (dh *deviceHandler) stopReconciling(ctx context.Context) {
3245 logger.Debugw(ctx, "stop reconciling", log.Fields{"device-id": dh.deviceID})
3246 if dh.isReconciling() {
3247 dh.chReconcilingFinished <- true
3248 } else {
3249 logger.Infow(ctx, "reconciling is not running", log.Fields{"device-id": dh.deviceID})
3250 }
3251}
3252
3253func (dh *deviceHandler) isReconciling() bool {
3254 dh.mutexReconcilingFlag.RLock()
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003255 defer dh.mutexReconcilingFlag.RUnlock()
3256 return dh.reconciling != cNoReconciling
3257}
3258
3259func (dh *deviceHandler) isSkipOnuConfigReconciling() bool {
3260 dh.mutexReconcilingFlag.RLock()
3261 defer dh.mutexReconcilingFlag.RUnlock()
3262 return dh.reconciling == cSkipOnuConfigReconciling
3263}
3264
3265func (dh *deviceHandler) setDeviceReason(value uint8) {
3266 dh.mutexDeviceReason.Lock()
3267 dh.deviceReason = value
3268 dh.mutexDeviceReason.Unlock()
3269}
3270
3271func (dh *deviceHandler) getDeviceReason() uint8 {
3272 dh.mutexDeviceReason.RLock()
3273 value := dh.deviceReason
3274 dh.mutexDeviceReason.RUnlock()
Holger Hildebrandtf37b3d72021-02-17 10:25:22 +00003275 return value
3276}
Holger Hildebrandtbe523842021-03-10 10:47:18 +00003277
3278func (dh *deviceHandler) getDeviceReasonString() string {
3279 return deviceReasonMap[dh.getDeviceReason()]
3280}
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00003281
3282func (dh *deviceHandler) setReconcilingFlows(value bool) {
3283 dh.mutexReconcilingFlowsFlag.Lock()
3284 dh.reconcilingFlows = value
3285 dh.mutexReconcilingFlowsFlag.Unlock()
3286}
3287
3288func (dh *deviceHandler) isReconcilingFlows() bool {
3289 dh.mutexReconcilingFlowsFlag.RLock()
3290 value := dh.reconcilingFlows
3291 dh.mutexReconcilingFlowsFlag.RUnlock()
3292 return value
3293}
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003294
3295func (dh *deviceHandler) setReadyForOmciConfig(flagValue bool) {
3296 dh.mutexReadyForOmciConfig.Lock()
3297 dh.readyForOmciConfig = flagValue
3298 dh.mutexReadyForOmciConfig.Unlock()
3299}
3300
3301func (dh *deviceHandler) isReadyForOmciConfig() bool {
3302 dh.mutexReadyForOmciConfig.RLock()
3303 flagValue := dh.readyForOmciConfig
3304 dh.mutexReadyForOmciConfig.RUnlock()
3305 return flagValue
3306}